Load empty / optional inline hasMany relationship with Ember data
When most people have trouble loading inline Ember models, I have a problem with the exact opposite.
Ember throws errors when trying to parse a record containing a relationship embedded
, where the content for that relationship hasMany
is an empty array.
How do I make inline Ember DataMany data optional or nullable?
I have a model.
App.Beat = DS.Model.extend({
notes: DS.hasMany('note', {
embedded: 'always',
defaultValue: []
}),
...
})
This model represents the association in the model Bar
, which is the association in the model Track
. It doesn't matter here.
This built-in relationship is hasMany
serialized with the following serializer.
// http://bl.ocks.org/slindberg/6817234
App.ApplicationSerializer = DS.RESTSerializer.extend({
// Extract embedded relations from the payload and load them into the store
normalizeRelationships: function(type, hash) {
var store = this.store;
this._super(type, hash);
type.eachRelationship(function(attr, relationship) {
var relatedTypeKey = relationship.type.typeKey;
if (relationship.options.embedded) {
if (relationship.kind === 'hasMany') {
hash[attr] = hash[attr].map(function(embeddedHash) {
// Normalize the record with the correct serializer for the type
var normalized = store.serializerFor(relatedTypeKey).normalize(relationship.type, embeddedHash, attr);
// If the record has no id, give it a GUID so relationship management works
if (!normalized.id) {
normalized.id = Ember.generateGuid(null, relatedTypeKey);
}
// Push the record into the store
store.push(relatedTypeKey, normalized);
// Return just the id, and the relation manager will take care of the rest
return normalized.id;
});
}
}
});
}
});
After successfully deserializing and loading the records into the storage, somewhere in the application a property bars
on Track
. If it Bar
has beats
one of which one of those beats
has none notes
(because it is a rest bit where no notes are played), then the following error occurs:
"You looked at the 'bars' to' relationship, but some related records were not loaded. Either make sure all of them are loaded with the parent record, or specify that the relationship is async (DS.hasMany ({async: true})) "
This error comes from the following statement in ember-data.js: hasRelationship:
Ember.assert("...", Ember.A(records).everyProperty('isEmpty', false));
where records
is an array bars
that contains bits that are optionally contained notes
.
So how do I make the relationship embedded
hasMany
optional so that it accepts an empty array of records?
source to share
I recommend using EmbeddedRecordsMixin
in the recent beta of Ember Data (10 or 11) and then see if you have an issue with inline records.
Your app serializer:
App.ApplicationSerializer = DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin,{
// probably nothing required here yet
});
And then in your Beat model serializer:
App.BeatSerializer = App.ApplicationSerializer.extend({
attrs: {
notes: { embedded: 'always' }
}
});
source to share