1

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 -->
1
  • First of all redefine messages as an empty array in your data object at the moment of its creation. Instead of $set, simply just assign the data.messages to this.messages, and also use a computed property to extract the messages from the data and iterate through it in the template. Commented Nov 4, 2017 at 0:02

2 Answers 2

1

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')
        })
    }
})
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.