Cannot read property 'title' of null using vuejs 3

Viewed 4563

i am new to vuejs3, i tried using json with vuejs3, i displayed the courses in view blog / index, and when clicking on a course in an index it redirect to details of that course clicks, in my case it gives me error: Uncaught (in promise) TypeError: Cannot read property 'title' of null.

blog/index.vue

<template lang="">
    <div class="row">
       <div class="col-md-6" v-for="post in posts">
          <h1><router-link :to="{ name: 'post-show', params: { id: post.id, slug: post.slug }}">{{ post.title }}</router-link></h1>
          <p class="lead">{{ post.content }}</p>
       </div>
    </div>
</template>
<script>
export default {
    data() {
      return {
         posts: []
      }
    },
    mounted() {
       fetch('http://localhost:5000/posts')
          .then(res => res.json())
          .then(data => this.posts = data)
          .catch(err => console.log(err))
    },
}
</script>

blog/show.vue

<template lang="">
   <h1>{{ post.title }}</h1>
   <p>{{ post.content }}</p>
</template>
<script>
export default {

    props: ['id', 'slug'],
    data(){
        return {
            post: null
        }
    },
    mounted() {
        fetch(`http://localhost:5000/posts/${this.id}`)
          .then(res => res.json())
          .then(data => this.post = data)
          .catch(err => console.log(err))
    }
}
</script>

Router/index.js

  {
        path: '/blog/:id/:slug',
        name: 'post-show',
        component: Show,
        props: true
      },

data/db.json

{
    "posts": [
        {
           "id": 1,
           "title"  : "learn angular",
           "slug"   : "learn-angular",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        },
        {
           "id": 2,
           "title"  : "learn react",
           "slug"   : "learn-react",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        },
        {
           "id": 3,
           "title"  : "learn laravel",
           "slug"   : "learn-laravel",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        },
        {
           "id": 4,
           "title"  : "learn symfony",
           "slug"   : "learn-symfony",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        },
        {
           "id": 5,
           "title"  : "learn jee",
           "slug"   : "learn-jee",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        },
        {
           "id": 6,
           "title"  : "learn php",
           "slug"   : "learn-oracle",
           "content": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione, possimus."
        }
     ],
     "users": []
}
1 Answers

The problem is with your blog/show.vue file.

Notice how in your data, post is set to null.

When your component mounts, it attempts to read post.title and post.content but it fails because post does not yet contain those properties.

The method to retrieve and set the post data is only run after the component has been mounted.

One way would be to not display the <h1> and <p> tags until post data is no longer null by using an attribute like v-if="post"

Alternatively, you can set some default values to your post by making it an object:

post: {
   title: '',
   content: '',
}

This way, when the component mounts, the properties title and content exist.

Lastly, you could use a ternary:

<h1>{{ post ? post.title: '' }}</h1>
<p>{{ post ? post.content: '' }}</p>

In this approach, if post exists it renders the properties - otherwise it renders an empty string.

Related