7

I'm trying to get this to work but I struggle with it. My Collection ends up empty when I check the success callback on fetch. It doesn't give me any clear errors thou during parse. Here's my code:

My collection:

VOR.Collections.GridItems = Backbone.Collection.extend({
        model : VOR.Models.GridItem,
        url: "assets/data/grid.json",
        parse: function(response){
            var self = this;

            _.each(response, function(griditem){
                switch(griditem.type){
                    case "news":
                        self.add(new VOR.Models.NewsGridItem(griditem));
                        break;
                    default:
                        self.add(new VOR.Models.StandardGridItem(griditem));
                        break;
                }
            });
        }
});

This is how I create the collection:

griditems = new VOR.Collections.GridItems();

griditems.fetch({
    error: function(e) {console.log(e);},
    success: function(msg) {
        console.log(msg)
    });

When I console log msg I get: Object { length=0, models=[0], _byId={...}, more...}

I've also logged the parse function in the collection and it runs thru the JSON file just fine...any ideas on what could be wrong here? The length of the msg object should be 5..i.e. that's how many times the parse function loops and (should) add a model to the collection.

Joel
  • 3,166
  • 5
  • 24
  • 29

3 Answers3

19

A nice way of handling this is to redefined the model attribute, which tell the collection how to add a new model to the collection, as explained in this POST : A Backbone.js Collection of multiple Model subclasses (thanks @rulfzid, who answered my question :))

In your case, you should be able to define the model attributes like this :

var VOR.Collections.GridItems = Backbone.Collection.extend({

  url: "assets/data/grid.json",

  model: function(attrs, options) {
    switch(attrs.type) {
      case "news":
        return new VOR.Models.NewsGridItem(attrs, options);
      default:
        return new VOR.Models.StandardGridItem(attrs, options);
    }
  }

});
Community
  • 1
  • 1
Tricote
  • 1,508
  • 1
  • 13
  • 21
  • Thanks for this! This is much better than doing it in `parse` because this for bootstrapped data as well. – philoye May 24 '12 at 18:41
  • I think that first line should be `var VOR.Collections.GridItems = Backbone.Collection.extend({` – marcos82 Oct 03 '14 at 14:04
1

It will be better to store your grid items in different collections and wrap them with model like this:

var model = Backbone.Model.extend({
    url: 'assets/data/grid.json'
    newsItems: Backbone.Collection.extend({
        model: VOR.Models.NewsGridItem
    }),
    standartItems: Backbone.Collection.extend({
        model: VOR.Models.StandardGridItem
    }),

    initialize: function() {
        this.newsItems = new this.newsItems();
        this.standartItems = new this.standartItems();

        this.newsItems.bind('all', function() {
            this.trigger.apply(this, arguments);
        }, this)
        this.standartItems.bind('all', function() {
            this.trigger.apply(this, arguments);
        }, this)
    },

    parse: function(request) {
        _.each(response, _.bind(function(griditem) {
            switch (griditem.type) {
                case "news":
                    this.newsItems.add(griditem);
                    break;
                default:
                    this.standartItems.add(griditem);
                    break;
            }
        }, this));
    }
})

model.fetch()
ant_Ti
  • 2,385
  • 16
  • 14
0
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse : function(resp) {
  return resp;
},

This is what the doc says you should do in parse. Whatever you return will be set as the collection starting array. This is where it is called from:

  options.success = function(resp) {
    collection[options.add ? 'add' : 'refresh'](collection.parse(resp), options);
    if (success) success(collection, resp);
  }

So I would suggest to change your parse to:

return _.map(response, function(griditem){
    switch(griditem.type){
        case "news":
            return new VOR.Models.NewsGridItem(griditem);
            break;
        default:
            return new VOR.Models.StandardGridItem(griditem);
            break;
    }
});
Julien
  • 9,216
  • 4
  • 37
  • 38