Reputation: 4091
I have an API that returns one resource at a time.
As an example, say I have two related resources:
Topics
Posts
Topics
hasMany Posts
, and Posts
belongsTo a Topic
.
According to the documentation (and everything I've tried and have been reading about), Ember-Data expects the JSON out of the API to be similar to the following, where both the data for Topic
and the data for Posts
are provided simultaneously.
"topic": {
"id": ...,
"title": ...,
"author": ...
},
"posts": [{
"id": ...,
"commenter": ...,
"text": ...
}, {
"id": ...,
"commenter": ...,
"text": ...
}]
As I mentioned at the start of the post, my API does not do this. It would return the Topic
data in one call, and the Posts
data for that Topic
in a second call. Changing my API to work exactly how Ember wants it is not an option.
My question is, how can I extend/override the RESTAdapter and RESTSerializer in Ember-Data to support loading data from multiple API calls? Is this even possible?
I tried following this example, but it looks like the data here is already loaded (it tries to sideload data that is already known to the system): http://mozmonkey.com/2013/12/loading-json-with-embedded-records-into-ember-data-1-0-0-beta/
I also tried to override the extractFindAll
function of the ApplicationSerializer
, but can't figure out how to get the rest (no pun intended) of the application to wait for all of the relationships to load. I iterate through all of the relationships on the model, and load their data, but I don't see a way to shuttle that data back into the original payload:
extractFindAll: function (store, type, payload, id, requestType) {
var promises = [];
type.eachRelationship(function (key, relationship) {
promise.push(Ember.RSVP.Promise(function (resolve, reject) {
this.store.find(key, payloadEntry[key]);
}));
});
// can't figure out how to get the relationship payloads
// back to the original payload
Ember.RSVP.addSettled(promises).then(function () {
return this._super(store, type, payload, id, requestType);
});
}
Any help is appreciated.
Upvotes: 0
Views: 468
Reputation: 47367
That exactly describes using the async
property.
App.Foo = DS.Model.extend({
bars: DS.hasMany('bar', {async: true});
})
App.Bar = DS.Model.extend({
baz: DS.attr()
})
App.FooAdapter = DS.RESTAdapter.extend({
//anything custom
});
App.BarAdapter = DS.RESTAdapter.extend({
//anything custom
});
App.ApplicationAdapter = DS.RESTAdapter;
to be a site wide adapter.App.FooSerializer = DS.RESTSerializer.extend({
//anything custom
});
App.BarSerializer = DS.RESTSerializer.extend({
//anything custom
});
Important to note, I was lazy and my mock response for bars always returns the same thing regardless of any call to /bar*
http://emberjs.jsbin.com/OxIDiVU/481/edit
Upvotes: 1