Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I'm having trouble updating an array that is displayed as a list. I'm trying to make Vue detect the changes using $set() (as explained in the documentation), but I can't make it work.

Here's my code:

this.choices = this.currentScene.choices;
for (i = 0; i < this.choices.length; i++) {
  choice = this.currentScene.choices[i];
  choice.parsedText = this.parseText(choice.text);
  this.choices.$set(i, choice);
}

Vue still doesn't update the view. What am I doing wrong? Thanks in advance!

Edit: Yes, "this" refers to the Vue instance.

share|improve this question
    
if this is the Vue instance, then this.choices.$set doesn't exists, because Vue defines a this.$set method for the instance, not for its data – Yerko Palma Feb 4 at 15:17
    
@YerkoPalma nope, the way OP is using it is correct as well. – Jeff Feb 4 at 15:23
    
really? I've never seen it like that in the docs – Yerko Palma Feb 4 at 15:41
up vote 2 down vote accepted

It would definitely be useful to have a JSfiddle of your code, but I'm going to take a crack anyways.

I'm not sure you need to use that function to update the array, since as the documentation points out, its only when you need to change the index of the item.

JavaScript has a built in function called .map that takes a callback function and returns a new array with the callback applied to each item.

For example, you could translate your function to this, assuming that .parseText is a method on the Vue class.

var self = this; // so that we can access the Vue class inside map

this.choices = this.currentScene.choices.map(function(choice) {
    choice.parsedText = self.parseText(choice.text);
    return choice;
});

And Vue should pick up those changes.

share|improve this answer
1  
Just wanted to suggest using map since each item in the array is being modified. Here's a fiddle I made to supplement the answer I don't have to write now ;) jsfiddle.net/ch12nc6j/1 – pawel Feb 4 at 15:16
    
That's excellent, you even mocked a modified return value in the function to illustrate! kudos. – pizzasynthesis Feb 4 at 15:18
    
Thanks a lot for your responses! However I was not able to get it to work even with the jsfiddle example... I couldn't figure out how to load json files in jsfiddle so I hosted it on my own server: nano.fi/gametest The updateChoices() function is on line 41, and the specific case is the "Save a village" button (it doesn't update even though the array does) – Nanofus Feb 4 at 23:40
    
The issue turned out to be the fact that I had not declared "parsedText" in the json I load the data from... I didn't think that could be a problem. Thank you anyway! – Nanofus Feb 5 at 13:50

You could use a computed property for this, so you never have to manually update the array. Anytime choices changes you would see the change reflected in this.parsedChoices:

computed: {
    parsedChoices: function(){

        return this.currentScene.choices.map(function(choice) {
            choice.parsedText = this.parseText(choice.text);
            return choice;
        }.bind(this)); // bind Vue class as value of `this` inside func

    }
}    
share|improve this answer
    
Nice, but shouldn't the curly brace on the line with bind be moved inward? – pizzasynthesis Feb 4 at 19:25
    
and I think you should use the object syntax parsedChoices: function() since computed is an object. – pizzasynthesis Feb 4 at 19:27
    
Thanks I missed that. @pizzasynthesis – Jeff Feb 4 at 19:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.