7

I am trying to iterate over models fetched by collection.

I have folowing piece of code:

initialize: function() {
                this.collection = new UserCollection();
                this.collection.fetch();
                this.render();
            },

            renderCollection: function() {
                console.log("rendering collection");
                this.collection.each(function(index,model){
                    console.log("model"); 
                });
                console.log(this.collection);
            },

render: function() {
                this.template = _.template(template, {});
                this.$el.html(this.template);
                // some other stuff
                this.renderCollection();
}

and results:

rendering collection

d {models: Array[0], length: 0, _byId: Object, constructor: function, model: function…}
_byId: Object
_idAttr: "id"
length: 4
models: Array[4]
0: d
_changing: false
_events: Object
_pending: false
_previousAttributes: Object
attributes: Object
created: "2013-02-13 09:22:42"
id: "1"
modified: "2013-02-13 09:22:42"
role: "admin"
username: "email@gmail.com"
__proto__: Object
changed: Object
cid: "c5"
collection: d
id: "1"
__proto__: e
1: d
2: d
3: d
length: 4
__proto__: Array[0]
__proto__: e
 user_list.js:25

So the fetch method did work - in object dump I can find 4 records fetched but iterating over the collection does not work...

user606521
  • 14,486
  • 30
  • 113
  • 204

2 Answers2

20

Doing each on collection gives model itself as an argument.

Try this:

this.collection.each(function(model){
  console.log(model); 
});

It should give you the model for the current iteration.

Cyclone
  • 1,580
  • 1
  • 8
  • 14
8

Based on the output you provided, it doesn't look like any "model" has been printed. It's probably caused by, when the .each() block is executed, this.collection may not have been completely fetched yet. This is due to the async nature of JavaScript.

Try this in your initialize method:

initialize: function() {
    var me = this;
    this.collection = new UserCollection();
    // Listen to 'reset' events from collection, so when .fetch() is completed and all
    // ready to go, it'll trigger .render() automatically.
    this.listenTo(this.collection, 'reset', this.render);
    this.collection.fetch();
},

The other way to handle this is to add a success handler on fetch, but I think listening to reset events should be sufficient in this case.

Hope this helps!

BTW, like Cyclone says, the handler for .each should just be a model without the index. :)

DashK
  • 2,640
  • 1
  • 22
  • 28
  • 1
    the issue could come as well from the server output that needs to be a valid array of json objects. i.e in php an indexed json_encoded array – Bill'o Mar 24 '14 at 08:48
  • 1
    Your iterator should either be: 'this.collection.each(function(model){...});' OR 'this.collection.each(function(model,index){...});' OP has index and model the wrong way around. – David Rust-Smith Apr 30 '14 at 13:46
  • I had to do an each over collection.models like this (not collection): http://stackoverflow.com/questions/11726943/for-loop-over-backbone-collection...this was my problem. – Kelly May 25 '14 at 15:50