Nick Flatow
Nick Flatow

Reputation: 55

Vue component results in infinite loop when updating data

Whenever I try to update medMins the function produces the correct results twice. However, Vue returns with

[Vue warn]: You may have an infinite update loop in a component render function.

I tried switching medMins to a computed property but got the same result. I was reading that the problem was that the component renders then I'm changing some component data during which some reactive data is changed causing it re-render... etc. Is there a way I can avoid this? Am I able to update medMins in this component or do I have to do some other way? Any help would be much appreciated.

Vue.component('day', {
    //props: ['items'] or
    props: {
        dayofweek: {
            type: Array,
            required: true
        },
        name:{
            type: String,
            default: 'Blarg'
        },
    },
    data: function() {
      return {
          medMins: 0
      }
    },
    methods: {
        updateMed: function(day) {
            this.medMins += Number(day.endTimeMillis/60000).toFixed()-Number(day.startTimeMillis/60000).toFixed()
        }
    },
    template: ''+
        '         <div>'+
        '           <h1>{{name}}</h1>\n' +
        '            <div class = "row">\n' +
        '                <div class ="col" v-for="day in dayofweek">{{day.activityType}}' +
        '                   <div v-if="`${day.activityType}` == 45" v-on="updateMed(day)"></div>' +
        '                </div>' +
        '            </div>' +
        '            <h1>{{medMins}}</h1>'+
        '         </div>',
    computed: {

    }
});

Upvotes: 3

Views: 2207

Answers (2)

Phil
Phil

Reputation: 164734

Sounds like you just want a computed property for medMins. Something like this

// no need for "data" as far as I can see
computed: {
  medMins () {
    return this.dayofweek.reduce((medMins, { activityType, endTimeMillis, startTimeMillis }) => {
      if (activityType == 45) {
        medMins += Number(endTimeMillis/60000).toFixed()-Number(startTimeMillis/60000).toFixed()
      }
      return medMins
    }, 0)
  }
},
template: `
    <div>
      <h1>{{name}}</h1>
      <div class = "row">
        <div class="col" v-for="day in dayofweek">
          {{day.activityType}}
        </div>
      </div>
      <h1>{{medMins}}</h1>
    </div>
`

This will produce a number for medMins that calculates your totals for all the 45 activity types.

Upvotes: 1

Varit J Patel
Varit J Patel

Reputation: 3520

In Vue world, v-on is an event listener but you need to mention which type event you need to listen.

Let's say if it is click event then

v-on:click="updateMed(day)"

Hope this helps!

Upvotes: 1

Related Questions