3

I am trying to populate a collection from a simple JSON file as part of learning backbone.js. But I can't get it to work.

The AJAX call is made (verified with FireBug), but the toJSON method returns undefined.

What am I doing wrong?

theModel =  Backbone.Model.extend();

theCollection = Backbone.Collection.extend({
    model: aModel,
    url: "source.json"
});

theView = Backbone.View.extend({
   el: $("#temp"),
   initialize: function () {
       this.collection = new theCollection();
       this.collection.fetch();
       this.render();
   },
   render : function () {
       $(this.el).html( this.collection.toJSON() ); // Returns blank
   }
});

var myView = new theView;

Here's my JSON:

[{
    "description": "Lorem ipsum..."
 },
 {
    "description": "Lorem ipsum..."
}]
T J
  • 42,762
  • 13
  • 83
  • 138
Industrial
  • 41,400
  • 69
  • 194
  • 289

2 Answers2

10

fetch is asynchronous, your collection won't yet be populated if you immediately call render. To solve this problem, you just have to bind the collection reset event (sync event for Backbone>=1.0) to the view render :

theView = Backbone.View.extend({
   el: $("#temp"),

   initialize: function () {
       this.collection = new theCollection();

       // for Backbone < 1.0
       this.collection.on("reset", this.render, this);

       // for Backbone >= 1.0
       this.collection.on("sync", this.render, this);

       this.collection.fetch();
   },

   render : function () {
    console.log( this.collection.toJSON() );
   }
});

Note the third argument of the bind method, giving the correct context to the method: http://documentcloud.github.com/backbone/#FAQ-this

nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • Thanks a lot for your answer to my question. That third argument is completely new to me. I guess that it's the same as doing `_.bindAll(this, 'render');` or just `_.bindAll(this);` to get the `this` available in all methods? – Industrial Dec 07 '11 at 20:44
  • 1
    Mostly, this syntax only binds the render method to this on reset events, whereas _.bindAll(this, 'render') bind render to this for all calls. – nikoshr Dec 08 '11 at 09:34
  • Thanks for the explanation. I am starting to get a hang of the difference of binding `this` and binding events now :) – Industrial Dec 09 '11 at 10:09
0

i believe the problem lies in your json

either you override the parse method on the collection, to work with your json

or you could change the json :)

[{
    "description": "Lorem ipsum..."
},
{
    "description": "Lorem ipsum..."
}]

i believe this is what your json should look like, just an array of your models.

Sander
  • 13,301
  • 15
  • 72
  • 97