VueJS - trouble understanding .$set and .$add

26.8k views Asked by At

I am trying to build an array of objects in VueJS and I am running into some issues with .$set and .$add.

For example, I need the following structure when adding new items/objects:

{
  "attendees": {
    "a32iaaidASDI": {
      "name": "Jane Doe",
      "userToken": "a32iaaidASDI",
      "agencies": [
        {
          "name": "Foo Co"
        }
      ]
    }
  }
}

New objects are added in response to an AJAX call that returns JSON formatted the same as above. Here is my Vue instance:

var vm = new Vue({
            el: '#trainingContainer',
            data: {
                attending: false,
                attendees: {}
            },
            methods: {
                setParticipantAttending: function(data)
                {
                    if (data.attending)
                    {
                        this.attendees.$add(data.userToken, data);
                    } else {
                        this.attendees.$delete(data.userToken);
                    }
                }
            }
        });

This only works if I start with attendees: {} in my data but when I try attendees.length after adding an attendee, I receive undefined. If I use attendees: [], the new object does not appear to be added. And lastly, if I use .$set(data.userToken, data) it does not add in the 'token':{data..} format required.

What could be the issue here? What is the correct way to use $.add when starting with an empty array of objects?

UPDATE

I found that it works if I set attendees: {} and then, when adding a new object,

if (data.userToken in this.attendees) {
    this.attendees.$set(data.userToken, data);
} else {
    this.attendees.$add(data.userToken, data);
}

Not sure if there is a better way to accomplish this.

2

There are 2 answers

3
David K. Hess On BEST ANSWER

If you set attendees to an empty object ({}) it will not have a length attribute. That attribute is on Arrays.

If you set attendees to an empty array ([]) then you need to use $set (or really, I think you want .push()) – $add is intended for use on objects not on arrays.

I'm not quite following your last question – could you add more context?

EDIT 2:

The answer below was for Vue 1.x. For Vue 2.x and greater use:

this.$set(this.attendees, data.userToken, data);

More information here: https://v2.vuejs.org/v2/api/#Vue-set

EDIT:

Responding to your update, you should be able to just use $set in all cases. I.e. just do this:

this.attendees.$set(data.userToken, data);
0
MECU On

As of version 0.6.0, this seems to be the correct way:

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

http://vuejs.org/guide/reactivity.html#Change_Detection_Caveats