How should async belongsTo relationships be serialized?

It looks like current serializeBelongsTo code attempts to load the relationship which results in a DS.PromiseObject. Trying to get the id property of the promise returns undefined. It seems like the code should access record.get('data')[relationship.key].id to get the ID of the async object. Or does it not make sense to serialize async relationships at all?

  serializeBelongsTo: function(record, json, relationship) {
    var key = relationship.key;
    var belongsTo = get(record, key);
    key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;

    if (isNone(belongsTo)) {
      json[key] = belongsTo;
    } else {
      json[key] = get(belongsTo, 'id');
    }

    if (relationship.options.polymorphic) {
      this.serializePolymorphicType(record, json, relationship);
    }
  }

Currently this is broken in ember-data core. I opened an issue a while back (waiting on a related pull request to make it in before making one for this specific issue). The related issue makes this return a promise so you can “resolve” the belongsTo

https://github.com/emberjs/data/issues/1542

@toranb, I did happen to see the issue you opened while looking into this, and after reconsidering it, I realize it would of course take care of the race condition I was observing. Thanks for the response! :smile:

I was wondering though: if the object already knows the async relationship’s ID via the _data property, can’t it just use that instead of trying to resolve the object?

I have places in my code that only use the related objects id and I’ve been able to do something like this

foo.get(‘bar.id’) //should work

Instead of this …

foo.get(‘bar’).get(‘id’) //breaks as it needs to resolve the promise first (and this won’t work)

I do this inside a filter to chop down a list of objects. Let me know if this works for you (I’m using a special adapter for django but I assume this is core ember-data so it should work regardless)

Oh, I didn’t know foo.get('bar.id') was semantically different from foo.get('bar').get('id'). How does the former work?

I keep going in loops in my head on the issue you mentioned. The related issue seems to be addressing async polymorphic relationships? Maybe I need to re-read the thread and the pull request. Regardless, shouldn’t the serialization code attempt to use data.id if it’s available in order to avoid sending a request out?

AFAIK var x = foo.get(‘bar’).get(‘id’) is the equvalent of this:

var x, tempvar;
tempvar = foo.get('bar');
// will cause an error if tempvar (ie bar's immediate value) is empty
x = tempvar.get('id');

whereas foo.get(‘bar.id’) is equivalent to this:

var x, tempvar;
tempvar = foo.get('bar');
// won't cause an error if tempvar (ie bar's immediate value) is empty
x = if(Ember.isEmpty(bar)) { return null; } else { return bar.get('id'); }

at least… that’s how they behave in my experience.

–EDIT– Oh apologies, I thought this was new for some reason. Sorry to dredge this up.

No worries, always good to pack more information into these threads regardless of how new they are. I often search old threads for answers to my questions! Thanks!