Iterating through a Backbone.PageableCollection not working

367 Views Asked by At

I have a Backbone.PageableCollection (@customers) whose models I would like to iterate through. I have tried many things -- including what I thought was obvious:

@customers.each (customer) ->
  console.log customer

Unfortunately, this logs out something that looks like a collection but has no model data in it. I know that the collection has been fully synced, because when I log out @customers.models I can see an array of model data:

enter image description here

Strangely, if I do this:

_.each @customers.models, (customer) ->
  console.log customer

I get the same, unhelpful result as above.

What am I missing?

Update:

Looking closer at the object logged by console.log customer in both approaches, this looks like a model with unpopulated attributes. This is strange since logging @customers.models shows an array of models with attributes fully populated. In addition, the each loop only executes once.

Update 2:

I tried the following per agconti's suggestion below:

@customers.each (@customers, c) ->
  console.log @customers, c

which compiles to:

      return this.customers.each((function(_this) {
        return function(customers, c) {
          _this.customers = customers;
          return console.log(_this.customer, c);
        };
      })(this));

and logs undefined and a 0.

Update 3:

If I set:

window.customers = @customers

and then enter this into the console:

_.each(customers.models, function (customer) { return console.log(customer)});

I get a log of all the customer models. I'm really confused now...

Update 4:

I've narrowed this down to a timing issue. I run this code after the collection has synced, but it seems that model parsing in the collection happens later.

3

There are 3 best solutions below

7
On

You need to specify an iterator for .each(). Do this instead:

@customers.each (@customers, c) ->
  console.log c

If you check the backbone docs on .each() you see that it takes in three properties; (list, iterator, [context]). Since you're just logging customer and not an iterator of the customer collection it just logs the entire collection.

0
On

This has turned out to be some problem in my fetching/syncing code. This code is not supposed to run until the customers collection is fully synced, but something (as yet undetermined) is allowing it to run before the collection is fully synced.

2
On

A backbone collection's models are stored at Collection.models, thats what you need to iterate over. when doing _.each @customers, you are iterating over the collection object's attributes, not its models so what you want is _.each @customers.models, (customer) -> console.log customer