Reputation: 3163
I'm dealing with a strange problem in Vue. I'm trying to display a list of employees in the table. Employees are provided by a REST service and response looks exactly like this (shown below is one item from the paginatedList):
{
"id": 10a,
"code": 0000,
"firstName": "John",
"lastName": "Doe",
"level": "WORKER",
"specialization": {
"id": 20,
"name": "Default",
"taem": {
"id": 2,
"name": "Builders",
"system": false,
"teamLead": null,
"specializationDtos": null,
"categoryDtos": null
}
},
"team": {
"id": 2,
"name": "Builders",
"system": false,
"teamLead": null,
"specializationDtos": null,
"categoryDtos": null
},
"coachDto": null,
"roles": [
"DL"
]
}
In Vue, I'm using Vuex actions to preprocess raw data and return paginated list of employees. Then I'm trying to print it in the table using v-for
like this:
<tr v-for="item in paginatedList" :key="item.id"
v-on:click="selectRow(item)"
v-bind:class="{selectedRow: selectedItem === item}"
>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.team.name}}</td>
</tr>
And this is where it fails (kind of). Even though the table is displayed with no employee missing the team name, I'm getting warning from Vue:
[Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"
After clicking on the line of code, which causes the warning, it points to the place where I'm trying to render {{item.team.name}}
My first thought was that the employee with missing team was simply not displayed. In order to check it I came up with following workaround:
<td>{{getTeamName(item.team)}}</td>
And the method:
getTeamName(team) {
return (team ? team.name : 'FAILED');
}
Warning/error disappears but there is no employee with FAILED team. What exactly is the problem with this? Is it possible to display properties of nested object like that or should I avoid it?
Upvotes: 1
Views: 2261
Reputation: 11
It looks as though you have mis-spelled team in your object:
"taem": {
"id": 2,
"name": "Builders",
"system": false,
"teamLead": null,
"specializationDtos": null,
"categoryDtos": null
}
which I guess is why it can't render name of undefined.
Upvotes: 0
Reputation: 15934
This can happen when the object your iterating doesn't yet have the data you're expecting but by the time you come to debug it, it does. I find this most often when using data which you're getting from a promise. With that in mind, just add a check to make sure that your data has loaded properly, in your case, this should suffice:
<tr v-for="item in paginatedList" :key="item.id"
v-on:click="selectRow(item)"
v-bind:class="{selectedRow: selectedItem === item}"
>
<div v-if="item.team">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.team.name}}</td>
</div>
</tr>
I generally have a dataLoaded
prop on my component which is initialised as false but set to true once I've finished messing with my data to avoid issues like this. I'd then check v-if="dataLoaded"
around my whole component.
Upvotes: 4