Search code examples
javascriptvue.jsvuejs2vue-componentv-for

Component v for doesn't recognise prop, if not explicitly declared while initializing object in root


In my root, I am declaring my (multidimensinal) object in data like so:

var app = new Vue({
    el: '#root',
    data: {
       accounts: {}
}

If I send the props like this:

<div id="root">
   <my-component :accounts="accounts"></my-component>
</div>

Also in component, accept props. In the component, I also have the template that I perform a for loop.

Vue.component('my-component', {
   props: ['accounts'],
   template `
       <div>
        <another-component v-for="(x, i) in accounts"></another-component>
       </div>
   `
})

In this case, where while I am initializing the accounts in the root, if I give it an empty object, it won't perform the loop.

If in for loop, instead of accounts, I use a digit, it performs the loop.

Also, while initializing in the root, if I become explicit...

accountTypes : {
     1: [],
     2: []
},

...the for loop works. However, this time I get another error:

Avoid using non-primitive value as key, use string/number value instead.

Also, I don't want to be explicit on 1 and 2, sometimes I don't want 2 to be there at all.


I am filling up accounts with a method in my root, binded to checkbox @change.

 methods: {
   accountSelected() {
       this.pushValue(index, name)
   },

   pushValue(key, value) {
        var obj = this.accounts

        if (obj.hasOwnProperty(key)) {
            var idx = $.inArray(value, obj[key]);
            if (idx == -1) {
                obj[key].push(value);
            }
        } else {
            obj[key] = [value];
        }
    },
 }

Solution

  • As mentioned in my comment above, Vue cannot detect when you add properties to an object after that object has been added to the Vue. Use $set in your else clause.

    pushValue(key, value) {
        var obj = this.accountTypes
    
        if (obj.hasOwnProperty(key)) {
            var idx = $.inArray(value, obj[key]);
            if (idx == -1) {
                obj[key].push(value);
            }
        } else {
            this.$set(obj, key, [value]);
        }
    },
    

    The error you are seeing with respect to a key is likely because you are setting a key during your loop:

    <another-component v-for="(x, i) in accounts" :key="x"></another-component>
    

    The problem here is that x is an array. i, however is just the key of accounts, so use that.

    <another-component v-for="(x, i) in accounts" :key="i"></another-component>