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?

+3


source to share


2 answers


It looks like it was isEmpty

in my model bar

that was conflicting with a property that was tested in the Ember assertion. Renaming this property made everything work.



0


source


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' }
  }
});

      

+1


source







All Articles