Skip to content
Advertisement

vue.js data not updating when incremented

I have an object containing an array, which gets incremented after some amount of logic has completed.

Vue.js doesn’t seem to be capturing this increment and displaying it to the view.

HTML:

<div id="demo">
  <p>{{points}}</p>
</div>

JS:

function Board()
{ 
  this.team1 = {pointsMade:[0]};
}

var newBoard = new Board();

newBoard.team1.pointsMade[0]++


new Vue({
  el: '#demo',
  data: {
    points: newBoard.team1.pointsMade
  }
})

setTimeout(newBoard.team1.pointsMade[0]++,1000)

I have a JSFiddle that outlines the problem.

You can see that after setTimeout(newBoard.team1.pointsMade[0]++,1000) runs, the value should be ‘2’, but is only displayed at ‘1’. What am I missing here?

Advertisement

Answer

When you define

  data: {
    points: newBoard.team1.pointsMade[0]
  }

the points variable is just assigned current value of newBoard.team1.pointsMade[0], which is 1 at this moment. There is no magic here. JS primitives works by value, not by references.

So, after updating the newBoard.team1.pointsMade[0] variable, the point variable is not updating of course.

To make this work, use object instead of primitive value. Objects work by reference in JS.

From Properties and Methods example:

var data = { a: 1 }
var vm = new Vue({
  data: data
})
vm.a === data.a // -> true
// setting the property also affects original data
vm.a = 2
data.a // -> 2
// ... and vice-versa
data.a = 3
vm.a // -> 3

edit

There is another caveat here:

Due to limitations in JavaScript, Vue cannot detect when you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue. So, use Vue.set(newBoard.team1.pointsMade, 0, newBoard.team1.pointsMade[0] + 1);.

I updated your fiddle.

Advertisement