1

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?

2
  • This is directly explained in the documentation vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats Commented Jan 2, 2017 at 3:38
  • @AndyRay Great, I"m quite new to Vue.js however and am confused by the documentation, how would you go about implementing a solution to my described issue? Commented Jan 2, 2017 at 3:41

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

What if I were to set the view data to newBoard.team1.pointsMade instead of newBoard.team1.pointsMade[0]. Doesn't that set it to a reference type? I will edit my question to reflect this
Yes, sorry, 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);.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.