Marcogomesr
Marcogomesr

Reputation: 2672

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

How come it doesn't show any error passing the title and description but it shows a Error in render: "TypeError: Cannot read property 'text' of undefined" on content.link.text

Parent

<template>
 <div>
  <splash :content="Splash"></splash>
 </div>
</template>

<script>
import Child from './Child.vue'

export default {
    name: 'Main',

    data () {
        Splash: {},
    },

    created () {
        const ax = axios.create({
        baseURL: '/static'
        })
        ax.get('content.json')
        .then(res => {

            this.Splash = res.data.general.splash

        })
    },

    components: {
        Splash
    }
   }
</script>

Child

<template>
    <div class="container">


        <h2>{{ content.title }}</h2>     // ok
        <p>{{ content.description }}</p> // ok              
        <p>{{ content.link.text }}</p>   // shows render error  
    </div>
</template>
<script>


export default {

    name: 'Splash',

    props: [
        'content'
    ]



}
</script>

content.json

{
    general : {
        splash : {
         "title" : "lorem title",
         "description" : "lorem description",
         "link" : { 
           "text" : "click me"
         }
        }
    }
}

Upvotes: 1

Views: 4124

Answers (2)

Djurdjen
Djurdjen

Reputation: 283

@Ausito already provided the answer. But I thought i'd put in an example.
Set Splash to null as default and put in v-if="Splash" in the splash component.

<template>
 <div>
  <splash v-if="Splash" :content="Splash"></splash>
 </div>
</template>

<script>
import Child from './Child.vue'

export default {
    name: 'Main',

    data () {
        Splash: null,
    },

    created () {
        const ax = axios.create({
        baseURL: '/static'
        })
        ax.get('content.json')
        .then(res => {
            this.Splash = res.data.general.splash
        })
    },

    components: {
        Splash
    }
   }
</script>

Upvotes: 2

Austio
Austio

Reputation: 6095

Most likely this is due to the value of content on first render. That is an empty object, which will return undefined for any property

content = {}
link = content.link // link is undefined
link.text // error

You should have a condition for first rendering so that you don't display the content unless it has a valid value.


Expanding

Your promise is in the created hook, but due to it being async it will only return data at some point after the current sync cycle finishes. By that time the Splash component will have already been created with the object that will cause the error.

If you are going to be doing a pattern like this where you will be fetching real data there are a few patterns you can use depending on how you want the user flow to work.

  1. Use lodash _.get to wrap all of your data that may or may not be there. Then your content.link.text would go in the computed properties and be something like return _.get(content, 'link.text'). This will cause it to properly return a value here.

  2. Don't render the Splash until the async request is complete, while loading show a loading

  3. Use v-if in your Splash component to guard

Out of these, i would say 2 is the best b/c it splits the concerns.

Upvotes: 0

Related Questions