3

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
  • You are getting Cannot read property 'title' of null inside show.vue component. The data post object is initialized as null, and only the fetch() function is populating it. Which means that the fetch() function doesn't return a value, or it fails for some reason. Commented May 2, 2021 at 17:34

1 Answer 1

14

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.