Algy Taylor
Algy Taylor

Reputation: 834

Parsing data in Backbone.js

I've got a number of backbone models which have a number of nested sub-models. My solution looks like this:

Models.Base = Backbone.Model.extend ({
    relatedModels:  {},

    /**
     * Parses data sent according to the list of related models.
     *
     * @since                   Version 1
     * @param {Object} response Response
     * @return {Object}         Parsed data
     */
    parse: function (response) {
        var key,
            embeddedClass,
            embeddedData;

        for (key in this.relatedModels) {
            embeddedClass = this.relatedModels[key];
            embeddedData = response[key];
            response[key] = new embeddedClass (embeddedData, { parse: true });
        }

        return response;
    }
});

(using stuff gleaned from this post - Nested Models in Backbone.js, how to approach)

This works fine whilst I'm getting stuff from the server:

Models.Individual = Models.Base.extend({
    idAttribute:    "idInd",
    urlRoot:    "data/individuals/save",

    relatedModels:  {
        details:        Collections.DetailList,
        relationships:  Collections.RelationshipList
    }
});

... but when I try and initialise a model from a plain bit of JSON, for example if I were to do this:

var Ind = new Models.Individual ({
    idInd: 1,
    name: "Bob Holness",
    details: [
        { option: "I'd like an 'e' please, bob" },
        { option: "Can I have a 'p' please, bob" }
    ],
    relationships: []
});

... it doesn't seem to want to parse "details". I'd guess that was because it's not running the Parse function, but anyway - how can I get it to parse the data in both instances?

Upvotes: 0

Views: 128

Answers (1)

Alex
Alex

Reputation: 1599

The easiest way to do it would be to pass parse: true to the constructor, like so:

var Ind = new Models.Individual ({
    idInd: 1,
    ...
}, { parse: true });

If you do this a lot you can override the constructor in your base class and make it pass parse: true every time you create a new model instance:

Models.Base = Backbone.Model.extend({
    constructor: function(attributes, options) {
        var opts = $.extend({}, options || {});
        if (_.isUndefined(opts.parse)) {
            opts.parse = true;
        }
        Backbone.Model.call(this, attributes, opts);
    },

    ...
});

Upvotes: 2

Related Questions