I have a fairly complicated model with a lot of hasMany and belongsTo relationships. When I save the parent model, instead of just the IDs, I want to save the contents of all nested objects as well.
Since this isn’t supported by default I thought I’d override serializeHasMany and belongsTo on the adapter. But it turns out my record object is a promise and invoking “then” to resolve it causes the object to be serialized without that property.
I suspect calling “then” sticks it on a queue of stuff to do. The end result is that the final JSOn doesn’t include promise fields.
I went further and got it almost working, but for some reason I’m missing fields in some cases, like “id”. Although the other properties of the nested object gets resolved and included in the final JSON.
Code I have so far is:
Impulse.ApplicationAdapter = DS.RESTAdapter.extend({
// namespace: 'api/1',
// host:''
updateRecord: function (store, type, record) {
record.set('_asyncResolving', Ember.ArrayProxy.create({content: []}));
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var id = record.get('id');
console.log('quote data', data);
// return this.ajax(this.buildURL(type.typeKey, id), "PUT", { data: data });
var $this = this;
function doSend(resolve, reject) {
$this.ajax($this.buildURL(type.typeKey, id), "PUT", { data: data }).then(function () {
resolve.apply($this, arguments)
},
function () {
reject.apply($this, arguments)
})
}
return new Ember.RSVP.Promise(function (resolve, reject) {
var outstanding = record.get('_asyncResolving'), expecting = outstanding.get('length'), success = 0, failure = 0;
outstanding.forEach(function (p) {
p.then(function () {
++success;
console.log(success, failure, expecting);
if (success + failure + 1 == expecting) {
doSend(resolve, reject)
}
}, function () {
++failure;
console.log(success, failure, expecting);
if (success + failure + 1 == expecting) {
doSend(resolve, reject)
}
})
})
});
}
});
DS.RESTSerializer.reopen({
//http://mozmonkey.com/2013/12/serializing-embedded-relationships-ember-data-beta/
serializeHasMany: function (record, json, relationship) {
var key = relationship.key,
hasManyRecord = record.get(key);
// Embed hasMany relationship if records exist
if (hasManyRecord && relationship.options.fat === true) {
record.get('_asyncResolving').addObject(new Ember.RSVP.Promise(function (resolve, reject) {
hasManyRecord.then(function (r) {
json[key] = [];
r.forEach(function (item, index) {
json[key].push(item.toJSON());
});
resolve(json)
})
}));
}
// Fallback to default serialization behavior
else {
return this._super(record, json, relationship);
}
},
serializeBelongsTo: function (record, json, relationship) {
var key = relationship.key,
belongsTo = record.get(key);
if (belongsTo && relationship.options.fat === true) {
record.get('_asyncResolving').addObject(new Ember.RSVP.Promise(function (resolve, reject) {
belongsTo.then(function (value) {
json[key] = value.toJSON();
resolve(json);
});
}));
}
else {
return this._super(record, json, relationship);
}
}
});
Is there another way to do this or any idea why I’m missing the id field? I really don’t want to make N PUT requests to save what can be a single request.