Skip to main content
  1. About
  2. For Teams
Asked
Viewed 5k times
2

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"
            }
        ]
    }
}
1
  • just add another v-for="subitem in item" element inside the first v-for element
    thanksd
    –  thanksd
    2017-08-16 17:56:51 +00:00
    Commented Aug 16, 2017 at 17:56

2 Answers 2

1

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/[email protected]/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>

Sign up to request clarification or add additional context in comments.

4 Comments

You should use a template in this case, not a slot
Edited, but may I know the reason why? I saw this, but maybe you have more accurate
<slot> is used to interweave content. <template> is simply logic that you want (in this case, an outer for loop) without any accompanying DOM node.
Like Terry said, use templates for content composition within a component, and slots for content distribution between components. Anything in an unnamed slot tag will be replaced by the contents of a component's tag. See this example: jsfiddle.net/q70aw981
1

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.

2 Comments

I'd rather use this than my solution nowadays! Especially because you can use array.flat. It can be used since chrome 69 or with babel. return Object.values(this.system_events).flat()
Thanks for the edit, @UlysseBN. And good point about array.flat.

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.