Pritam Bohra
Pritam Bohra

Reputation: 4339

Recursive components in Vue js

I using vue components to display comments as well as replies to the comments. To display the replies I am simply using comment component recursively. however, I am getting an error.

Here's my code

<template>
    <div class="box">
        <article class="media">
            <figure class="media-left">
                <p class="image is-64x64">
                    <img :src="comment.channel.data.imageUrl">
                </p>
            </figure>
            <div class="media-content">
                <div class="content">
                    <p>
                        <strong><a :href="channelUrl">{{ comment.channel.data.name }}</a></strong> <small>{{ comment.created_at_human }}</small>
                        <br>
                        <p class="is-medium">{{ comment.body }}</p>
                        <nav class="level is-mobile">
                            <div class="level-left">
                                <a class="level-item">
                                    <span class="icon is-small"><i class="fa fa-comment-o"></i></span>
                                </a>
                            </div>
                        </nav>
                    </p>
                </div>
            </div>
        </article>
       <comment v-for="reply in comment.replies.data" :comment="reply" :key="reply.id"></comment>
</div>

I am getting the following error:

[Vue warn]: Error in render function: "TypeError: Cannot read property 'data' of undefined"

found in

---> <Reply> at /home/vagrant/Laravel/youtube/resources/assets/js/components/Comment.vue... (1 recursive calls)
       <VideoComments> at /home/vagrant/Laravel/youtube/resources/assets/js/components/VideoComments.vue
         <VideoPlayerLayout> at /home/vagrant/Laravel/youtube/resources/assets/js/components/VideoPlayerLayout.vue
           <Root>

Data is available in the object as I am using fractal to generate json output. Don't really know where am I going wrong.

Upvotes: 1

Views: 1546

Answers (1)

Bert
Bert

Reputation: 82499

There are three places in the template where you are referencing a data property that is a third tier nested property, comment.channel.data.imageUrl, comment.replies.data, and comment.channel.data.name.

If at any time, comment.channel or comment.replies is undefined, you will see this error.

For the replies you could guard it this way:

<template v-if="comment.replies">
  <comment v-for="reply in comment.replies.data" :comment="reply" :key="reply.id"></comment>
</template>

For comment.channel.data.name you could use

{{comment.channel && comment.channel.data && comment.channel.data.name }}

For comment.channel.data.imageUrl you could use

<p v-if="comment.channel && comment.channel.data" class="image is-64x64">
  <img :src="comment.channel.data.imageUrl">
</p>

Upvotes: 2

Related Questions