0

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.

Erik
  • 7,479
  • 8
  • 62
  • 99
  • what is the returned when you log `@customers`? – agconti Feb 12 '14 at 04:37
  • I updated update 2 also. This syntax makes no sense to me though. I still would expect `@customers.each (customer) -> console.log customer` to work. – Erik Feb 12 '14 at 04:56
  • Thats the problem. if `this.customers` is undefined then `.each()` cannot iterate through it. Try creating a test collection and test iterating through that, and then track down why customers inst defined. Can you share more of your code? – agconti Feb 12 '14 at 04:59
  • The syntax you suggested is clobbering `@customers` which is why it is logging `undefined`. I log out `@customers` right before the `each` clause and it is fully defined. The mystery is why logging `@customers.models[0]` logs an unpopulated model and why the `each` loop iterates only once. – Erik Feb 12 '14 at 05:03

3 Answers3

0

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.

agconti
  • 17,780
  • 15
  • 80
  • 114
  • That sounds like a good point that I will try shortly, but the backbone documentation does not mention an iterator. It shows: books.each(function(book) { book.publish(); }); – Erik Feb 12 '14 at 03:47
  • @Erik I'm not familiar with the paginator plugin so let me know if it works out :) – agconti Feb 12 '14 at 03:50
  • No joy. `console.log c` logs 0. There are 52 customers and this only happens once. – Erik Feb 12 '14 at 04:03
  • @Erik did you try it the underscore way with `_.each (customer, c) ->`? – agconti Feb 12 '14 at 04:04
  • Same result when I do it the underscore way. – Erik Feb 12 '14 at 04:10
  • @Erik what does your coffeescript build to? I dont think the each method is getting the function it expects. it should be `this.customers.each(function(this.customer, c){console.log(c);});` – agconti Feb 12 '14 at 04:13
  • @Erik Also! We both for got to specify the list correctly as the collection `@customers`. try that and let me know if it works. I updated my answer as well. – agconti Feb 12 '14 at 04:15
0

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

michael truong
  • 321
  • 1
  • 4
  • 1
    Yep, which is what I am doing i the second code example. The backbone docs also say that `@customers.each (customer) -> console.log customer` should work too -- which is what I have tried in the first code sample. – Erik Feb 12 '14 at 16:33
  • oops, sorry i missed that. – michael truong Feb 12 '14 at 17:03
0

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.

Erik
  • 7,479
  • 8
  • 62
  • 99