model.save() destroys nested collection
Closed this issue · 7 comments
Hi!
I have a problem with nested collections using your localStorage adapter.
I want so store GPS-Data whereas one GPS-track is represented with one title and many positions.
Positions are defined as a Backbone.Collection:
TrackModel = Backbone.Model.extend({
defaults: {
title: "",
positions: new PositionsCollection()
}
})
PositionsCollection = Backbone.Collection.extend({
model: PositionModel
});
PositionModel = Backbone.Model.extend({
defaults: {
latitude: "",
longitude: "",
timestamp: ""
}
});
My data-structure should look like that:
{
"title": "TrackTitle,
"positions": [{
"latitude": "...",
"longitude": "...",
"timestamp":"..." }],
[{
"latitude": "...",
"longitude": "...",
"timestamp":"..."
}],
...
}
The nesting works fine until i save the complete track with track.save() to localStorage.
Then my PositionsCollection in memory turns into a blank Javascript-Array.
After saving I can't do something like track.get("positions"), which was possible before.
Saving the data to localStorage works. At initialization of my app I'm parsing the json-data like that:
parse: function(response) {
_.each(response, function(track){
track.positions = new PositionsCollection(track.positions);
});
return response;
}
After fetching the data from localStorage everything is fine again.
But I need to keep my positions in memory as a Backbone Collection as well.
Many thanks in advance for your help.
Best
I've encountered the same problem.
The nested collection turns into a blank Javascript Array when localStorage serializes the model, calling JSON.stringify(model)
.
According to the manual:
If an object being stringified has a property named toJSON whose value is a function, then the toJSON() method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON() method when called will be serialized.
So when localStorage serializes the model, it calls model.toJSON()
, the default Backbone toJSON, that it simply clones the model's attributes, excluding the nested collection.
A simple solution would be to change the behavior of the model toJSON()
to include the nested collection.
I hope this can help you and future readers. 😄
@coire1, I can understand the issue. but can't fix yet. Can you help on this. I meet the same issue on my project
regards
Bao jingjing
Hi, it is really an old project but I found the piece of code you need.
In the model that contains the nested collection you have to redefine and override the toJSON
method.
The new method has to initialize a new collection and copy the models in it.
toJSON: function() {
/* Get the array as model attribute */
var tempNestedModels = this.get('nestedCollection');
if (!tempNestedModels) {
/* if are present nested models initialize a new collection */
nestedModels = new NestedCollection();
}
/* for each model in collection copy/filter the attributes needed */
_.each(nestedModels.models, function(model) {
model.attributes = _.pick(model.attributes, 'id', 'exampleAttr');
});
/* return the original model, filtering out unuseful attributes and adding
the new collection instead of the original array */
return _.merge(_.pick(this.attributes, 'id', 'modelAttr'), {
nestedCollection: nestedModels
});
}
Hi @coire1, do you happen to have the Backbone version for this? I've synchronised nested collections to the server in Backbone 1.3+ and it's all serialized correctly. If it's fixed upstream, I'll close this ticket.