Error in render: "TypeError: Cannot read property 'first_name' of undefined"

Viewed 1962

I'm working on a small project using VueJS / Axios. I'm getting an error in my console log :

Error in render: "TypeError: Cannot read property 'first_name' of undefined"

Since I'm getting and showing the first_name correctly ( i see the result in my page ) the problem just in the console

this is my code :

export default {
    data(){
        return {
            collection:{
                data: []
            }
        }
    },
    created: function(){
        getAPI.get('/api/contacts/1/', [{'x':'10'}]).then((response) => {
            this.collection.data = response.data
        })
    }
}

HTML code :

<span class="d-block info-content">
    {{collection.data.contactInfos.first_name}}
</span>

By the way i see the result i see the name, in my HTML, but just i'm wondering about my console log error since the code work perfectly

4 Answers

You may try to load the data, when it's not there yet, use conditional rendering:

<span class="d-block info-content" v-if="collection.data && collection.data.contactInfos">
    {{collection.data.contactInfos.first_name}}
</span>

More information

Update

If collection.data is an array then try to show the first element's contactInfos:

{{collection.data[0].contactInfos.first_name}}

For an explanation of what's going on, the created() hook does not block. Therefore the rendering of your page merrily proceeds, until your <span> element is rendered. At that point, the injection {{collection.data.contactInfos.first_name}} is evaluated, and your console logs the given error, which, as the message itself suggests, happens during render.

Later, after the Promise in the created() hook resolves and data is updated, the Vue engine re-renders the components with a dependency on data, and the text node inside <span> is updated.

To avoid this kind of issue, you must make sure to not reference properties until the loading has completed. You can do this by setting an if condition on your element, for example:

<span class="d-block info-content" v-if="!loadingData">
    {{collection.data.contactInfos.first_name}}
</span>

and updating loadingData only after the promise is resolved:

export default {
    data(){
        return {
            collection:{
                data: []
            },
            loadingData: true
        }
    },
    created: function(){
        getAPI.get('/api/contacts/1/', [{'x':'10'}]).then((response) => {
            this.collection.data = response.data
            this.loadingData = false
        })
    }
}

I believe your response is coming back as unparsed JSON. Can you try:

this.collection.data = JSON.parse(response.data)

You can try the ternary condition, to get rid of this error first, like this

{{collection.data.contactInfos ? collection.data.contactInfos.first_name : ""}}

then try to figure out where this property got missing from that object.

Related