laravel Vue.js: Ошибка при рендеринге: «Ошибка типа: не удается прочитать свойство 'user' из null" - PullRequest
1 голос
/ 08 октября 2019

Я создаю систему комментирования, используя Vue.js и laravel 5.8. Я хочу показать комментарии на странице поста в блоге (show.blade.php), но я получил ошибку

Ошибка при рендеринге: "TypeError: Невозможно прочитать свойство 'user' из null"

В моем инструменте Chrome Vue Dev я могу получать объекты, но не могу отображать комментарии.

Я хочу получить и показать имя пользователя и комментарий пользователя.

Я рад, если кто-то мне поможет.

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>

Ответы [ 3 ]

1 голос
/ 08 октября 2019

Вы получаете данные от axios и используете их как Paginator, но axios отвечает на собственный объект AxiosResponse, тогда у вас есть в AxiosResponse один объект, такой как

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

Я думаю, в этом проблема. Вам нужно установить для комментариев что-то вроде:

this.comments = data.data;
0 голосов
/ 08 октября 2019

Спасибо, ребята, я мог бы решить эту проблему, изменив v-for = "comment in comments.data.data": key = "comment.id".

0 голосов
/ 08 октября 2019

Взят из официальных документов (выделение мной второго абзаца):

Использование v-if и v-for вместе не рекомендуется . См. Руководство по стилю для получения дополнительной информации.

При использовании вместе с v-if, v-for имеет более высокий приоритет, чем v-if . Подробнее см. Руководство по визуализации списка 1017 *.

Итак, вы не можете использовать comment из оператора v-for, он недоступен при оценке v-if. Поэтому он не определен и не может иметь свойства user, которое объясняет сообщение об ошибке.

См. Предлагаемые решения, ссылки на которые приведены в официальных документах, и цитату выше. Например, вы можете иметь вычисляемое свойство, которое предварительно фильтрует comments.data только для тех комметов, для которых установлено user.

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

И затем вместо этого используйте v-for="comment in commentsWithUser".

Дополнительное примечание: Вы также должны указать значение :key при использовании v-for. Это должно быть что-то уникальное для каждого отображаемого элемента, поэтому, если ваши комментарии имеют идентификатор, скажем, в comments.data[...].id, тогда :key="comment.id" v-for="comment in comments.data" будет иметь смысл.

...