[Vuejs]-Accessing a multi-dimensional object from inside a v-for

0đź‘Ť

âś…

As OP states in the comment, data property=list is created or updated async by axios.

In order to avoid the error vue.js:597 [Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined", one solution is uses v-if to make sure {{ list[bar].name }} will be rendered only when bar in list.

So you should change your template to below:

<li v-for="bar in foo.bars" v-if="list[bar]">{{ list[bar].name }}</li>

0đź‘Ť

So, thanks to @Sphinx’s suggestion, here is the answer in all it’s code glory: http://jsfiddle.net/megalomaniac/8j7otq0h/

<div id='app' v-cloak>
  <div v-for='foo in things'>
    <h3>{{ foo.title }}</h3>
    <div>
      <ul>
        <li v-for="bar in foo.bars" v-if="list[bar]">{{ list[bar].name }}</li>
        <!-- <li v-for="bar in foo.bars">Doesn't work: {{ list[bar].name }}</li> -->
      </ul>
    </div>
    <div v-html="foo.description"></div>
  </div>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    list: {
      "somekey":{"name":"Joe Bloggs","email":"joe.bloggs@"},
      "someotherkey":{"name":"John Doe","email":"john.doe@"},
      "anotherkey":{"name":"A N Other","email":"a.n.other@"}
    },
    things: [{"title":"Title01","bars":["somekey"],"description":"Desc01"},
      {"title":"Title02","bars":["someotherkey","anotherkey"],"description":"Desc02"},
      {"title":"Title03","bars":["somekey","brokenkey"],"description":"Desc03"},
      {"title":"Title03","bars":["somekey","anotherkey"],"description":"Desc03"}]
  }
})
</script>

Basically I needed to account for instances when the some of the data might be bad or missing (look for “brokenkey” in the JSFiddle). While this does apply to async issues in my case is wasn’t because of async but because the some data was actually missing – which was the one thing I thought I could be certain wasn’t at fault (that’ll teach me to think testing the returned JSON’s validity, the existence of the objects in the console, trusting the source, etc. were enough of a check).

Leave a comment