1

I am creating commenting system using Vue.js and laravel 5.8. I want to show comments in blog post page (show.blade.php) but I got an error

Error in render: "TypeError: Cannot read property 'user' of null"

In my chrome vue dev tool, I could get objects, but I cannot show comments.

I want to retrieve and show user name and user's comment.

I am glad if someone helps me out.

comments.vue

<template>
<div class="commentarea" > 
    <div class="comment-posts" >
        <div class="user-comment-area" >
            <div class="user-post">
                <!---<img src="{{asset('people/person7.jpg')}}" class="image-preview__image">--->
                <input type="text" name="comment">
            </div>
            <div class="comments-buttons">
                <button class="cancel-button">Cancel</button>
                <button class="comment-button" type="submit">Comment</button>
            </div>
        </div>
        <h4>Comments ()</h4>

        <div class="reply-comment" v-if="comment.user" v-for="comment in comments.data">
                <div class="user-comment">
                <div class="user">
                    <!---<img src="{{ $comment->user->img }}" class="image-preview__image">--->
                    <avatar :username="comment.user.name"></avatar>
                </div>
                <div class="user-name">
                    <span class="comment-name">{{ comment.user.name }}</span>
                    <p>{{ comment.body }}</p>
                </div>
            </div>
            <div class="reply">
                <div class="seemorecomments">
                    <a href="">see more</a>
                </div>
                <button class="reply-button">
                    <i class="fas fa-reply"></i>
                </button>
            </div>
        </div>
    </div>
    <div>
        <button  class="load">Load More</button>
    </div>
</div>
</template>

<script>
import Avatar from 'vue-avatar'
export default {
    props: ['post'],
    components: {
        Avatar
    },
    mounted() {
        this.fetchComments()
    },
    data: () => ({
        comments: {
            data: []
        }
    }),
    methods: {
        fetchComments() {
            axios.get(`/results/${this.post.id}/comments`).then((data) => {
                this.comments = data
            })
            .catch(function (error) {
            console.log(error.response);
            })
        }
    }
}
</script>

web.php

Route::get('results/{post}/comments', 'CommentController@index');

ResultsController.php

public function show(Post $post)
{
    $recommended_posts = Post::latest()
                        ->whereDate('date','>',date('Y-m-d'))
                        ->where('category_id','=',$post->category_id)
                        ->where('id','!=',$post->id)
                        ->limit(7)
                        ->get();

    // load the post comments here
    $post->load('comments');
    $posts['particular_post'] = $post;
    $posts['recommended_posts'] = $recommended_posts;

    return view('posts.show',compact('posts'));
}

CommentsController.php

public function index(Post $post)
{
    return $post->comments()->with('user')->paginate(5);
}

comment.php

 protected $with = ['user'];

show.blade.php

<comments-component :post="{{ $posts['particular_post'] }}"></comments-component>
1
  • Can you provide a dump of what fetchComments returns in Vue? Seems like the relationship isn't being bought in Commented Oct 8, 2019 at 14:04

3 Answers 3

1

You're getting data from axios, and use it like Paginator, but axios response a own AxiosResponse object, then, you have in AxiosResponse one object like

{
   status: 200,
   data : {}  <= Your paginator is here
}

I think is that the problem. You need to set to comments something like:

this.comments = data.data;
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks it worked, but how can I show next 5 comments ?
You're asking duplicate questions @YoheiUmezu . You've already asked this in a separate thread.
Actually the diffrence is v-for="comment in comments.data". In my previous question, I could solve the problem. But I got an issue for paginating, so I changed v-for part.
@YoheiUmezu If you want to show the next 5 comments, you need to save the current page, and total pages, and depend of them, show a "Read more" button or something like that and load the next page. Or course, your request need to receive the page param too.
0

Thank you guys, I could solve this by changing to v-for="comment in comments.data.data" :key="comment.id".

Comments

0

Taken from the official docs (highlighting of the second paragraph by me):

Using v-if and v-for together is not recommended. See the style guide for further information.

When used together with v-if, v-for has a higher priority than v-if. See the list rendering guide for details.

So, you cannot use the comment from the v-for statement, it's not available when v-if is being evaluated. Therefore it's undefined and cannot have a user property, which explains the error message.

See the proposed solutions linked to from the official docs and the quote above. You could for example have a computed property that pre-filters comments.data for only those commetns that have user set.

computed: {
  commentsWithUser: function() {
    return this.comments.filter(c => { return c.user });
  }
}

And then use v-for="comment in commentsWithUser" instead.

Additional note: You should also supply a :key value when using v-for. It has to be something unique for each rendered element, so if your comments have an ID, let's say in comments.data[...].id, then :key="comment.id" v-for="comment in comments.data" would make sense.

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.