1
votes

I have a model, which has a backbone collection as one of its attributes.

If I output the model, I can see the collection and all looks ok.

If I output the result of the collection toJSON(), it apparently outputs the whole of the collection object as json.

So the following two lines:

console.log('about to sync', model);
console.log('files', model.attributes.files.toJSON());

Gives the following output:

Console output in Chrome 44

As you can see, the collection is present and correct in the model, but the toJSON call returns all of the functions in the object as well as the models and so on, instead of "an array containing the attributes hash of each model in the collection"

3

3 Answers

2
votes

Backbone doesn't handle sub models/collections by default, you have to plug in your desired behavior. In your case, you just have to override toJSON on your model to replace the collection by its array representation.

Something like

var M = Backbone.Model.extend({
    toJSON: function() {
        var json = Backbone.Model.prototype.toJSON.call(this);
        json.files = this.get('files').toJSON();
        return json;
    }
});

And a demo http://jsfiddle.net/nikoshr/1jk8gLz4/


Or if you prefer a more general change, alter Backbone.Model.prototype.toJSON to include this behaviour for all models. For example

(function () {
    var originalMethod = Backbone.Model.prototype.toJSON;

    Backbone.Model.prototype.toJSON = function(options) {
        var json = originalMethod.call(this, options);

        _.each(json, function(value, key) {
            if ((value instanceof Backbone.Collection) ||
                (value instanceof Backbone.Model))
                json[key] = value.toJSON();
        });

        return json;
    };
})();

http://jsfiddle.net/nikoshr/1jk8gLz4/2/

0
votes

Tom, You will need to loop through each element in the object to see the contents after you have done toJSON(). I have also faced same problem. See how to parse the JSON object. While printing there would be any issues.

Hope this helps!!

Thanks

0
votes

override toJSON method.

var yourModel = Backbone.Model.extend({
    toJSON: function(){
      var base = Backbone.Model.prototype.toJSON.call(this);
      for (key in base) {
        item = base[key];
        if (item.toJSON != null) {
          base[key] = item.toJSON();
        }
      }
      return base;
    }
});