user7503162
user7503162

Reputation: 21

How do I loop through an array of objects using v-for in Vue.js?

I'm struggling with iterating through this array of objects. I'm not seeing any console errors and not sure why the data is not displaying.

{
 "messages":[
  {
    "id":1,
    "sender":"frank",
    "message":"Lorem ipsum...",
    "time":1398894261,
    "status":"read"
  },
  {
    "id":2,
    "sender":"mary",
    "message":"Lorem ipsum...",
    "time":1390824261,
    "status":"read"
  },
  {
    "id":3,
    "sender":"john",
    "message":"Lorem ipsum...",
    "time":1308744200,
    "status":"unread"
  }
 ]
}

I'm using an http get request and the data is coming in, but I can't iterate through it. Here's my js:

new Vue({
    el: '#app',
    data: '',
    ready: function() {
      // GET request
      this.$http.get('https://www.example.com/file.json', function (data) {
        // set data on vm
        this.$set('data', data.messages);
        }).error(function (data, status, request) {
            console.log('http request error')
        })
    }
  })

And here's my html:

<div v-if="data">
  <li v-for="d in data">{{ d.sender }}</li>
</div>
<p>{{data[0].sender}}</p> <!-- this part works -->

Upvotes: 1

Views: 3842

Answers (2)

Paul Tsai
Paul Tsai

Reputation: 1009

In the callback of AJAX request, this is NOT vm, you can solve this by

  1. use arrow function
  2. use var vm = this
  3. use .bind(this)

this pen use arrow function: https://codepen.io/iampaul83/pen/bYpqgm

arrow function:

new Vue({
    el: '#app',
    data: '',
    ready: function () {
        // GET request
        this.$http.get('https://www.example.com/file.json', (data) => {
            // set data on vm
            this.$set('data', data.messages);
        }).error(function (data, status, request) {
            console.log('http request error')
        })
    }
})

var vm = this:

new Vue({
    el: '#app',
    data: '',
    ready: function () {
        // GET request
        var vm = this
        this.$http.get('https://www.example.com/file.json', function (data) {
            // set data on vm
            vm.$set('data', data.messages);
        }).error(function (data, status, request) {
            console.log('http request error')
        })
    }
})

.bind(this):

new Vue({
    el: '#app',
    data: '',
    ready: function () {
        // GET request
        this.$http.get('https://www.example.com/file.json', function (data) {
            // set data on vm
            this.$set('data', data.messages);
        }.bind(this)).error(function (data, status, request) {
            console.log('http request error')
        })
    }
})

Upvotes: 1

Tarik Chakur
Tarik Chakur

Reputation: 1737

Your problem might be due to vue.js deep reactivity limitation.( check vue's documentation ) My suggestion is to use push instead of using this.$set loop through your response and push the result one element by one in messages variable which u will declare in your data object.

data.messages.forEach( (msg ) => { this.messages.push( msg ); }

In your template loop through the messages variable.

Upvotes: 0

Related Questions