Converting JSON data to a base model with a child collection

I am working with a Playlist object that has some properties defining itself as well as a PlaylistItem collection.

When I receive data from my server, I receive a JSON response in my client side success method:

success: function (data) {
    console.log("JSON data:", data);

    playlists = _.map(data, function (playlistConfig) {
        return new Playlist(playlistConfig);
    });

    ...
}

      

Here I am converting JSON data to Playlist objects. Each Playlist object is a .Model base.

This is what my data looks like:

enter image description here

And this is what the playlist constructor looks like:

return function(config) {
    var playlist = new Playlist(config);

    return playlist;
};

var Playlist = Backbone.Model.extend({
    defaults: function() {
        return {
            id: null,
            userId: null,
            title: 'New Playlist',
            selected: false,
            position: 0,
            shuffledItems: [],
            history: [],
            items: Backbone.Collection.extend({
                model: PlaylistItem
            })
        };
    },
    ...
}

      

My problem:

If I create a Playlist object with default values, it is initialized with an empty Backbone.Collection for the PlaylistItem. However, if I create a Playlist object with a collection already defined, I get the underlying array and not the Backbone.Collection. This is because I am working with JSON data from a server that has not yet been converted to Backbone objects. This data propagates to the playlist defaults and overwrites the Backbone.Collection object.

What is the correct way to initialize with a filled Backbone.Collection? I could write code in Initializes that checks the type of my items array and if it is not Backbone.Collection I could create a new Backbone.Collection and add items to it and then replace the old array with a new one, but that seems really hoakey ...

+3


source to share


2 answers


Don't define your PlalistItems collection inside default values, but in advance. Then create an initialization method in your playlist model, for example:

var PlaylistItems = Backbone.Collection.extend({
   ...
});

var Playlist = Backbone.Model.extend({
    initialize: function() {
        this.set('items', new PlaylistItems(this.items));
    },

    defaults: function() {
        return {
            id: null,
            userId: null,
            title: 'New Playlist',
            selected: false,
            position: 0,
            shuffledItems: [],
            history: [],
            items: []  // don't define your PlaylistItems Collection here
        };
}
});

      



Have a look at the fiddle here: http://jsfiddle.net/georgedyer/r2XKb/ (you need to open your console to see the collection)

+1


source


Another problem I ran into was that after saving your model to the server, you get a response that will change your inline collection into a regular javascript array. To fix this, I had to override the parsing function in my model class as follows:



var model = backbone.Model.extend({
        urlRoot : "/rest/model",

        initialize: function(){
            this.set("myCollection", new MyCollection(this.myArray));
        },

        defaults: {
            myArray: []
        },

        parse: function(response){
            this.set(response);
            this.set("myArray", new MyCollection(response.myArray));
        }
    });

      

0


source







All Articles