Reputation: 2672
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
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
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.
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.
Don't render the Splash until the async request is complete, while loading show a loading
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