1

I have the following problem: My API returns null - no data available. (that's good!). My collection gets the data but creates one single empty object.

My API result (from Firebug):

{"data":{"objects":null}}

My collection:

var MyCollection = Backbone.Collection.extend({
    model: MyModel,
    url: '/v1/ajax/load-objects',

    parse: function(resp, xhr) {
        return resp.data.objects;
    }
});

When I print self.model.toJSON() in my view (the model is the collection), I get this (by Firebug):

 [Object {}]

My question: Why is the collection putting one empty bject in my collection? The API returns null, so it should be empty.

I tried adding default values to my model (which the collection uses), they are not shown. So I guess it's taking the null as the data for one object. How can I stop him doing this?

Thx

Ron

Ron
  • 22,128
  • 31
  • 108
  • 206
  • 1
    Have you tried returning an empty array (`[]`) when `objects` is null? IIRC Backbone expects an array to be returned from `parse`. I'd guess it sees you returning a single object (null) and assumes you wanted a one-element long array. – ivarni Feb 22 '16 at 13:07
  • good point, I'll give it a try – Ron Feb 22 '16 at 13:09

2 Answers2

2

If you poke around Backbone's source code, you'll see that models inside a collection are handled by Collection.set

Once Collection.set has parsed your data, it performs a check on what you actually returned and creates an array if the value (null in your case) is not an array :

var singular = !_.isArray(models);
models = singular ? [models] : models.slice();

This list of models is then processed and creates a single model in your collection.

The solution is simple : return an empty array when you hit a null value in parse :

var MyCollection = Backbone.Collection.extend({
    model: MyModel,
    url: '/v1/ajax/load-objects',

    parse: function(resp, xhr) {
        return resp.data.objects || [];
    }
});

And a demo simulating your problem http://jsfiddle.net/nikoshr/s2dve9ob/ and its solution : http://jsfiddle.net/nikoshr/s2dve9ob/1/

nikoshr
  • 32,926
  • 33
  • 91
  • 105
0

Ok, now it seems to work. But I really don't get why :)

I added (empty) defaults to my model. Now it works.

var MyModel = Backbone.Model.extend({
    defaults: {
    },

    initialize: function () {
        var self = this;
    }
});
Ron
  • 22,128
  • 31
  • 108
  • 206