0

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.

3
  • 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 Commented Feb 4, 2016 at 15:17
  • @YerkoPalma nope, the way OP is using it is correct as well. Commented Feb 4, 2016 at 15:23
  • really? I've never seen it like that in the docs Commented Feb 4, 2016 at 15:41

2 Answers 2

2

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.

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

4 Comments

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
That's excellent, you even mocked a modified return value in the function to illustrate! kudos.
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)
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!
1

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

    }
}    

3 Comments

Nice, but shouldn't the curly brace on the line with bind be moved inward?
and I think you should use the object syntax parsedChoices: function() since computed is an object.
Thanks I missed that. @pizzasynthesis

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.