Jeremy P. Beasley
Jeremy P. Beasley

Reputation: 709

How to loop through JSON/API data inside a component template with Vue.js

I've got a functioning snippet rending a list of songs here: https://jsfiddle.net/jeremypbeasley/guraav4r/8/

var apiURL = "https://ws.audioscrobbler.com/2.0/?method=user.gettoptracks&user=thisisheroic&period=7day&limit=6&api_key=3cbc1a3aa903935d08223263bcc3ba0b&format=json";

new Vue({
  el: '#demo',
  data: {
    commits: null
  },
  created: function () {
    this.fetchData()
  },
  methods: {
    fetchData: function () {
      var xhr = new XMLHttpRequest()
      var self = this
      xhr.open('GET', apiURL)
      xhr.onload = function () {
        self.commits = JSON.parse(xhr.responseText)
      }
      xhr.send()
    }
  }
})

html:

<div id="demo">
  <h1>Tracks</h1>
  <li v-for="mytrack in commits.toptracks.track">
      {{mytrack.name}}
  </li>
</div>

The problem is that when I attempt to use this same general method in the context of a component, it breaks and logs two errors:

First: [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions. and another telling me that commits.toptracks is undefined.

My failed attempt:

Vue.component('manage-posts', {
  template: '#manage-template',
  data: {
    commits: null,
  },
  created: function () {
    this.fetchData()
  },
  methods: {
    fetchData: function () {
      var xhr = new XMLHttpRequest()
      xhr.open('GET', apiURL)
      xhr.onload = function () {
        this.data = JSON.parse(xhr.responseText);
        console.log(JSON.parse(xhr.responseText));
      }
      xhr.send()
    }
  }
})

Any help making sense of these errors and helping me understand what I'm doing wrong would be much appreciated!

Upvotes: 1

Views: 1151

Answers (1)

Martin St&#229;lberg
Martin St&#229;lberg

Reputation: 832

First: You define the data property as an object literal, instead you should use a function that returns an object literal when executed. For example:

...
data: () => ({
    commits: null
}),
...

Second: In the function fetchData, in the function you assign to xhr.onload, it may be that this refers to the xhr object when xhr.onload executes.

Side note: You might want to look up vue-resource, it's more convenient than using XMLHttpRequest.

Upvotes: 2

Related Questions