[Vuejs]-How to update the value through event in the v-for in a vue -template

0👍

When you receive the Event inside Echo:

listen(){
      Echo.channel('progress')
          .listen('UpdatedValue', (e) =>{

            let ToUpdate = this.progress.find(x => x.id === e.target)
            ToUpdate.value = e.value;
            //console.log(e);

    });

0👍

The issue with Vue’s reactivity, is that it wont trigger if you update nested properties. So if you were to find the progress item you wanted and updated its value, it would not be reflected until something forced it to re-render.

I think you should be able to do the following. By modifying the array the v-for is based on, you should get the reactivity you desire.

For the following solution to work, you need to be returning some identifying information in the listen event that is also available in the progress data item. Ideally, as in my following solution, the event returns an object with the same properties as whats in the progress array. As such,

listen(){
    Echo.channel('progress').listen('UpdatedValue', (e) => {
        const idx = this.progress.findIndex((item) => {
            return item.id = e.id;
        });
        
        if (idx < 0) {
            this.progress.push(e);
        } else {
            this.progress.splice(idx, 1, e);
        }
    });

0👍

You can try something like this

<template>
  <div class="container">
    <h1>Progress</h1>
    <div class="progress" v-for="p in progress" :key="p.id">
      <div>{{ p.goal }}</div>
      <div>{{ p.value }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      progress: [],
    };
  },
  mounted() {
    this.loadContents();
    this.listen();
  },
  methods: {
    loadContents: function() {
      axios
        .get('/api/progress')
        .then(response => (this.progress = response.data.data))
        .catch(error => console.log(error));
    },
    listen() {
      Echo.channel('progress').listen('UpdatedValue', progress => {
        // console.log(this.progress, progress);
        this.progress = this.progress.map(p => {
          // You should have something common here. May be id or any other key that you can compare to find the element in the progress array
          if (p.id == progress.id) {
            p.value = progress.value;
          }
          return p;
        });
      });
    },
  },
};
</script>

If it doesn’t work, you can uncomment log line and let me know the result.

<div id="div2" v-html="progressdata.value"></div> can be changed with <div>{{ progressdata.value }}</div> if there is no html to update but just number.

Example on CodeSandBox

Leave a comment