0

I am returning a collection of objects returned from a Mongodb database and want to find how many models were returned and be able to iterate through them and create some DOM elements based on that. I am not using a Backbone.View and will be using Famo.us.

I create a collection and get it returned BUT I can't seem to access the models inside or their data - wondered if you could help :)

Here is the Model/Collection:

define( function (require, exports, module) {
  'use strict';

  var Backbone = require('backbone');

  var Book = Backbone.Model.extend({
    idAttribute: "_id"
  });

  var BookCollection = Backbone.Collection.extend({
    model: Book,
    url: "http://localhost:3000/api/books"
  });
  module.exports = BookCollection;
});

In the main file I Instantiate the Collection using:

    this._bookCollection = new BookCollection();
    this._bookCollection.fetch({reset: true});

    var _bookCollection = this._bookCollection;
    console.log(_bookCollection);
    console.log(_bookCollection.length);

The 'console.log(_bookCollection)' will return something similar to:

n {length: 0, models: Array[0], _byId: Object, constructor: function, model: function…}
_byId: Object
length: 250
models: Array[250]
[0 … 99]
[100 … 199]
[200 … 249]
length: 250
__proto__: Array[0]
__proto__: s

So I know it returns something as I am expecting 250 'models' to be returned. As its not really an array - you can't do _bookCollection.length (well it doesn't work for me). How can I iterate through what is returned so I can get each model and then 'do' something with that model? I am using Famo.us so want to create something other than a Backbone.View.

Thanks

-- Update

after "this._bookCollection.fetch({add:true});" the browser shows I have :

 {length: 0, models: Array[0], _byId: Object, _events: Object, constructor: function…}_byId: Object_events: Objectlength: 250models: Array[250]__proto__: n

If you expand it, it tells you the length is 250 and in 'models' (Array[250]) there is the data I am looking for, split into [00..99], [100..199] etc.

Am I retrieving the collection incorrectly or can't I really do it without creating a view?

Pandafinity
  • 713
  • 2
  • 7
  • 19

2 Answers2

2

Collection.fetch is asynchronous, your data won't be immediately available. You will have to use either the promise returned by fetch:

_bookCollection.fetch({reset: true}).then(function() {
    console.log(_bookCollection.length, _bookCollection.pluck('_id'));
});

or the events provided by Backbone :

_bookCollection.on("sync", function() {
    console.log(_bookCollection.length, _bookCollection.pluck('_id'));
});
_bookCollection.fetch({reset: true});

Once your callbacks are set up, you can use whatever means of rendering suits you.

Bonus : why console.log tripped you

Community
  • 1
  • 1
nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • Thanks for telling me about the 'sync'. Could I 'pluck' more than one attribute at a time so I can get the values of each model? – Pandafinity Nov 06 '14 at 15:36
  • I'm not sure I understand what you want. You can manipulate the models however you want : for example, `Collection.toJSON` to get all the models serialized, or use the Underscore methods proxied on the collection http://backbonejs.org/#Collection-Underscore-Methods – nikoshr Nov 06 '14 at 15:50
  • If I try Collection.toJSON it comes back empty.I've update question with what I see – Pandafinity Nov 06 '14 at 16:25
0

Underscore.js functions should serve you well. I'm not sure what you want to do with the models in the collection, but check out http://underscorejs.org/ it has quite a few methods that will handle backbone collections. For example you could do

_.toArray(_bookCollection).length
frajk
  • 853
  • 6
  • 14