hauge
hauge

Reputation: 1535

Nested array loop in vue?

How would I loop a JSON object like the one below with v-for? I want to loop all ID's/Numbers, and all items in inside each number, and display it all in a list... I know I can loop all system_events easily using v-for="item in system_events" But how do I loop all different ID's/Numbers, and all items inside ?

My JSON looks like:

{
    "system_events": {
        "1013": [{
                "id": 25899,
                "timestamp": "2017-08-15T21:26:42Z",
                "type": "alarm",
                "code": 190,
                "title": "",
                "description": "",
                "appeared": "2017-08-15T21:26:40Z",
                "disappeared": null,
                "acknowlegded": null,
                "solved": null,
                "system_name": "Randers pr 44b sidste station"
            }, {
                "id": 26157,
                "timestamp": "2017-08-15T21:32:17Z",
                "type": "alarm",
                "code": 190,
                "title": "",
                "description": "",
                "appeared": "2017-08-15T21:32:06Z",
                "disappeared": null,
                "acknowlegded": null,
                "solved": null,
                "system_name": "Randers pr 44b sidste station"
            }
        ],
        "1015": [{
                "id": 23777,
                "timestamp": "2017-08-15T20:38:08Z",
                "type": "alarm",
                "code": 191,
                "title": "",
                "description": "",
                "appeared": "2017-08-15T20:38:00Z",
                "disappeared": null,
                "acknowlegded": null,
                "solved": null,
                "system_name": "Favrskov Svenstrup gyvelvej"
            }, {
                "id": 23779,
                "timestamp": "2017-08-15T20:38:08Z",
                "type": "alarm",
                "code": 190,
                "title": "",
                "description": "",
                "appeared": "2017-08-15T20:37:58Z",
                "disappeared": null,
                "acknowlegded": null,
                "solved": null,
                "system_name": "Favrskov Svenstrup gyvelvej"
            }
        ]
    }
}

Upvotes: 2

Views: 5185

Answers (2)

Erik Ostrom
Erik Ostrom

Reputation: 201

Another approach is to use a computed property to simplify your data structure:

new Vue({
  el: '#app',
  data: {
    system_events: {"1013":[{"id":25899},{"id":26157}],"1015":[{"id":23777},{"id":23779}]}    
  },
  computed: {
    allEvents: function() {
      return Object.values(this.system_events)
        .reduce((a, b) => a.concat(b), [])
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <ul>
    <li v-for="event in allEvents">{{event.id}}</li>
  </ul>
</div>

This allows you to use a simple loop in the template, which makes the structure of your markup clearer.

If you're working with large data sets, and/or the data are mutated frequently, you might want to test both these approaches for performance. I have no idea which one would be better.

Upvotes: 1

Ulysse BN
Ulysse BN

Reputation: 11423

In addition to Bert's answer, I'll say you can use a template tag in order not to render the main frame. This is useful for instance if you want a clean HTML ul>li only for subitems.

const vue = new Vue({
  el: "#app",
  data: {
    system_events: {"1013":[{"id":25899},{"id":26157}],"1015":[{"id":23777},{"id":23779}]}
  }
});
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>

<div id="app">
  <ul>
    <template v-for="item in system_events">
      <li v-for="event in item">{{ event.id }}</li>
    </template>
  </ul>
</div>

Upvotes: 1

Related Questions