0

This data is coming from the controller, and I have it in the mounted and in the data like so

data() {
    return {
        forum: [],
    }
},
mounted() {
    if (this.$page.forum) {
        this.forum = this.$page.forum;
    }
}

I have this data, it's very long so I won't be posting it all but there should be 13 comments total.

{ 
   "id":1,
   "theme":"werwer",
   "description":"werwer",
   "user_id":1,
   "anonymous":0,
   "start_date":"2019-12-01 06:00:00",
   "end_date":"2019-12-20 12:00:00",
   "created_at":"2019-12-04 12:00:50",
   "updated_at":"2019-12-09 08:15:47",
   "user":{ 
      "id":1,
      "name":"sadmin",
      "card":"1111",
      "scard":"123",
      "user_type_id":1,
      "email":"sadmin@gmail.com",
      "created_at":"2019-12-04 12:00:14",
      "updated_at":"2019-12-04 12:00:14"
   },
   "comments":[ 
      { 
         "id":5,
         "user_id":1,
         "discussion_forum_id":1,
         "parent_id":3,
         "comment":"Este comentario ha sido eliminado.",
         "comment_time":"2019-12-09 08:58:10",
         "deleted":1,
         "created_at":"2019-12-04 12:09:19",
         "updated_at":"2019-12-09 08:58:10",
         "user":{ 
            "id":1,
            "name":"sadmin",
            "card":"1111",
            "scard":"123",
            "user_type_id":1,
            "email":"sadmin@gmail.com",
            "created_at":"2019-12-04 12:00:14",
            "updated_at":"2019-12-04 12:00:14"
         },
         "replies":[ 
            { 
               "id":6,
               "user_id":1,
               "discussion_forum_id":1,
               "parent_id":5,
               "comment":"reply to reply",
               "comment_time":"2019-12-04 12:15:19",
               "deleted":0,
               "created_at":"2019-12-04 12:15:19",
               "updated_at":"2019-12-04 12:15:19",
               "user":{ 
                  "id":1,
                  "name":"sadmin",
                  "card":"1111",
                  "scard":"123",
                  "user_type_id":1,
                  "email":"sadmin@gmail.com",
                  "created_at":"2019-12-04 12:00:14",
                  "updated_at":"2019-12-04 12:00:14"
               }
            }
         ]
      },
   ]
}

I want to get the comments length so I tried {{forum.comments.length}} and am using it like this

<div v-if="forum.comments.length === 0">
    <el-card>
        <p>
          No comments!
        </p>
    </el-card>
</div>
<div v-else>
    <div v-for="comment in forum.comments">
        <el-card>
            //show comments
        </el-card>
    </div>
</div>

How ever I get these errors

Error in render: "TypeError: Cannot read property 'length' of undefined"

Cannot read property 'length' of undefined at <div v-if="forum.comments.length === 0">

The code itself works, and does the expected but still gets those 2 errors always. What is the correct way to do this and get rid of these errors?

Community
  • 1
  • 1
Nancy
  • 1,021
  • 4
  • 23
  • 45
  • 1
    Is the data coming from an api? `forum.comments` may be null initially until the data is retrieved, but then it renders as you said normally after it is mounted. Try `v-if="forum.comments === undefined || forum.comments.length === 0"` – chrisbyte Dec 09 '19 at 15:17
  • Please check this one https://stackoverflow.com/a/6700/3742822 – Kapil Paul Dec 09 '19 at 15:17
  • 1
    @chrisbyte +1. Caution : it will only work if forum is initialized with {} as value or will still throw an error with primitive types. Anyway, its chainable : `v-if="forum && forum.comments && forum.comments.length === 0"` – Bertrand Dec 09 '19 at 15:19
  • The problem isn't with the forum object but with your vue.js component's data initialization. Your component snippet doesn't have access to the forum object. So can you please post the relevant vue.js component script and data model. – Ananda Masri Dec 09 '19 at 15:20
  • @chrisbyte I have edited the question to add where the data is coming from – Nancy Dec 09 '19 at 15:25
  • @nancy when the component renders the forum object is just an array. Try ```data() { return { forum: { comments: [ ] } } }```, for the initial data – Ananda Masri Dec 09 '19 at 16:10

1 Answers1

1

Assuming the explanation is your data is loaded asynchronously and not available at component rendering.

The solution is to wrap your template into a whole check for forum.comments existence to avoid rendering the block before data is loaded. For instance :

<template v-if="forum && Array.isArray(forum.comments)">
  <div v-if="forum.comments.length === 0">
      <el-card>
          <p>
            No comments!
          </p>
      </el-card>
  </div>
  <div v-else>
      <div v-for="comment in forum.comments">
          <el-card>
              //show comments
          </el-card>
      </div>
  </div>
</template>
Bertrand
  • 1,840
  • 14
  • 22