2
votes

I have a parent component that contains an array and an object:

    data() {
        return {
            products: [],
            attributes: {},
        }
    },

When my parent component is loaded, it gets some AJAX data and populates the variables:

    mounted() {
        axios.get('/requests/getProducts/' + this.currentCategory).then(response => {
            this.products = response.data;
            this.createAttributes(); // runs some methods to populate the attributes object
        });
    }, 

I then have a child component that I will use to display the attributes. Code from parent template:

    <search-attributes :attributes="attributes"></search-attributes>

I have the props declared in my child component:

    props: ['attributes'],

So far so good, I can console log the data from parent and child...

Problem is when I try to v-for the attributes in the child component, it simply returns nothing:

/////////////// this does not render anything ///////////////

<template>
    <div>
        <div v-for="(value, key) in attributes">
            {{ key }}
        </div>
    </div>
</template>

However, if I pass both the products and attributes variables to the child component, and render products in the child component, attributes will start working!

/////////////// this works /////////////
<template>
    <div>
        <div v-for="(value, key) in attributes">
            {{ key }}
        </div>
    {{ products }}
    </div>
</template>

What the heck is going on?

Do you need to see my parent methods?

1
try make attributes computed property and prop it down to the children?Mikhail
can you just dump attributes in your template to see what is going onsamayo

1 Answers

5
votes

I expect you are running into a change detection caveat. Vue cannot detect when you add properties dynamically to an object. In this case, you begin with an empty attributes object. If you add properties to it without using $set, then Vue does not understand a change has occurred and will not update the DOM.

Update the createAttributes to use $set.

The reason it works when you pass products is Vue can detect the change you make (this.products = response.data), so it renders the DOM, which shows the latest attributes as a by product.