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.