0

The following code makes it look as if the "reset" event on the AccItemList collection is firing before the fetch is complete. The output to the console for this is as follows...

rendering

0

fetched

0

... so "render" is called before there are any models in the collection, which is clearly wrong, but just as confusingly even in the fetch success callback there don't seem to be any models in the collection. I have also tried instantiating the AccItemList collection in the router initializer, but that didn't make any different. I'm sure I'm missing something fundamental, please help, this is driving me crazy!

$(function () {

    var AccItem = Backbone.Model.extend({
        defaults: {}
    });

    var AccItemList = Backbone.Collection.extend({
        model: AccItem,
        url: "/Dashboard/Accommodation",
        parse: function (response) {
            this.add(response.AccItems);
        }
    });

    var AccListView = Backbone.View.extend({
        el: $("#temp"),
        initialize: function () {
            _.bindAll(this, 'render', 'renderAccItem');
            this.collection = new AccItemList();
            this.collection.on('reset', this.render);
            var that = this;
            that.collection.fetch({
                success: function () {
                    console.log("fetched");
                    console.log(that.collection.models.length);
                }
            });
        },
        render: function () {
            var that = this;
            console.log("rendering");
            console.log(this.collection.models.length);
        }
    });

    var App = Backbone.Router.extend({
        routes: {
            "": "index"
        },
        index: function () {
        },
        init: function () {
            var accItemView = new AccListView();
        }
    });

    var app = new App();
    app.init();

});
centralscru
  • 6,580
  • 3
  • 32
  • 43

1 Answers1

6

In AccItemList.parse, you manually add the models and don't return anything but Backbone doc states

parse collection.parse(response)

parse is called by Backbone whenever a collection's models are returned by the server, in fetch. The function is passed the raw response object, and should return the array of model attributes to be added to the collection. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to work with a preexisting API, or better namespace your responses. Note that afterwards, if your model class already has a parse function, it will be run against each fetched model.

Try

var AccItemList = Backbone.Collection.extend({
    model: AccItem,
    url: "/Dashboard/Accommodation",
    parse: function (response) {
        return response.AccItems;
    }
});

A Fiddle simulating your code and a modified version : http://jsfiddle.net/nikoshr/Q25dp/

The order in which the reset event and your success callback are called is dependent on the actual implementation in Backbone source. See http://documentcloud.github.com/backbone/docs/backbone.html#section-98

var success = options.success;
options.success = function(resp, status, xhr) {
    //reset call
    collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);

    //custom success call
    if (success) success(collection, resp);
};
nikoshr
  • 32,926
  • 33
  • 91
  • 105