Reputation: 762
I have a NuxtJS project linked to DatoCMS. A list of posts are displayed, click on a post title etc and get taken to the _slug.vue
page displaying more information. When I click on the post title I get taken to the _slug.vue
page, where I'm told 'Cannot read property 'title' of undefined'. However, if I refresh that page, it works fine. I can go back and forth between the homepage and the post page without any problems, until I view a different post page, and then the problem happens again until I reload the page. I can't work out what's going on.
index.vue
in the Pages directory:
<template>
<main>
<div v-for="(post, index) in allPosts" :key="index">
<div>
<h3>Generic Header</h3>
<p>Introduction paragraph</p>
</div>
<div>
<div>
<div
v-for="(post, index) in allPosts">
<ProductCard :post="post"/>
</div>
</div>
</div>
</div>
</main>
</template>
<script>
import ProductCard from "@/components/ProductCard";
import gql from "graphql-tag";
export default {
components: {
ProductCard
},
apollo: {
allPosts: gql`
{
allPosts {
title
text
slug
}
}
`
}
};
</script>
The productCard.vue
component in the Components directory, which gets called above, has no code in the bottom script tag, just a nuxt-link to the _slug.vue
file.
<nuxt-link :to="post.slug" prefetch>{{ post.title }}</nuxt-link>
The _slug.vue
file:
<template>
<div>
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
</div>
</template>
<script>
import gql from "graphql-tag";
export default {
apollo: {
post: {
query: gql`
query Post($slug: String!) {
post(filter: { slug: { eq: $slug } }) {
title
text
}
}
`,
prefetch({ route }) {
return {
slug: route.params.slug
};
},
variables() {
return {
slug: this.$route.params.slug
};
}
}
}
};
</script>
This is the output from the console:
TypeError: Cannot read property 'title' of undefined
at Proxy.render (webpack-internal:///./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./pages/_slug.vue?vue&type=template&id=286199e1&:9)
at VueComponent.Vue._render (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3542)
at VueComponent.updateComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4049)
at Watcher.get (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4473)
at new Watcher (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4462)
at mountComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4067)
at VueComponent.Vue.$mount (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:8405)
at init (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3115)
at merged (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3298)
at createComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:5968)
I have checked the other answers regarding 'Cannot read property 'title' of undefined' but they don't help in this instance, unfortunately.
Many thanks with any help. 👍 Matt
Upvotes: 2
Views: 1907
Reputation: 444
Could you provide the code of the ProductCard.vue
component?
My first assumption based on your question: If there is no code in the script
tag you won't be able to use the post property in the template
part.
Add this snippet in the script
part:
export default {
name: 'ProductCard',
props: {
post: Object
}
}
Find further information here: https://v2.vuejs.org/v2/guide/components-props.html
Upvotes: 1
Reputation: 553
I had the same error and i came to your post to find an answer but i just fixed it be removing this part from my _slug.vue
data() {
return {
categories: [],
}
},
this is my Links component
<template>
<div>
<div
class="grid w-full grid-cols-1 2xl:grid-cols-4 xl:grid-cols-4 lg:grid-cols-3 sm:grid-cols-2 gap-x-6 gap-y-12"
>
<!-- Product Tile Start -->
<div v-for="link in links" :key="link.id">
<div>
<div class="bg-white border rounded-t-lg shadow-sm">
<div class="relative pb-146/3">
<img
class="absolute object-cover w-full h-full rounded-t-lg"
:src="getStrapiMedia(link.thumbnail.formats.large.url)"
/>
</div>
<div class="relative w-full p-4 bg-white">
<a
:href="link.url"
target="_blank"
class="mb-2 text-base font-medium text-gray-800 truncate hover:text-indigo-500"
>
<p class="truncate">{{ link.title }}</p>
</a>
<p class="text-xs text-gray-600 truncate">
{{ link.description }}
</p>
<div class="flex flex-wrap items-center mt-6 justify-starts">
<span
v-for="tag in link.tags"
:key="tag.id"
class="px-2 py-1 mr-1 text-xs leading-none text-indigo-600 bg-indigo-200 rounded"
>{{ tag.name }}</span
>
</div>
</div>
</div>
</div>
</div>
<!-- Product Tile End -->
</div>
</div>
</template>
<script>
import { getStrapiMedia } from '../utils/medias'
export default {
props: {
links: {
type: Array,
default() {
return []
},
},
},
methods: {
getStrapiMedia,
},
}
</script>
and my pages/_slug.vue where i fixed the issue
<template>
<div v-if="categories">
<h1 class="w-full mb-4 text-2xl font-light text-left text-gray-600">
{{ categories[0].name }}
</h1>
<Links :links="categories[0].links || []"></Links>
</div>
</template>
<script>
import linksQuery from '~/apollo/queries/link/categories'
export default {
// REMOVING THIS DATA ELEMENT FIXED MY ISSUE
// data() {
// return {
// categories: [],
// }
// },
apollo: {
categories: {
prefetch: true,
query: linksQuery,
variables() {
return { slug: this.$route.params.id }
},
},
},
}
</script>
i hope this reference can help any other users
Upvotes: 0
Reputation: 19
You cannot print uninitialized post object. To avoid this error, just wrap it via v-if="post"
<template>
<div v-if="post">
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
</div>
</template>
Upvotes: 1