Given the following router, with a fairly straight forward routing synatx:
App.Router.map(function () {
this.resource('foos', function(){
this.resource('foo', { path: '/:foo_id' }, function(){
this.route('bar');
});
});
});
I have FoosController
, and FooBarController
, with corresponding routes for each: FoosRoute
and FooBarRoute
.
Both routes have a model
hook that returns a promise, which is obtained from ic.ajax
.
When I navigate to /foos
, and then navigate to /foos/123/bar
, the following sequence happens:
FoosRoute#model
make XHR request to GET /api/foos
/api/foos
FooBarRoute#model
makes an XHR request to GET /api/foos/123
/api/foos/123
This is great, and my app works fine. Next I naigate directly to /foos/123/bar
, the following sequence happens:
FoosRoute#model
make XHR request to GET /api/foos
FooBarRoute#model
makes an XHR request to GET /api/foos/123
/api/foos/123
/api/foos
The model
hooks for both FoosRoute
and FooBarRoute
fire in quick succession.
The server takes a longer time to return the response from /api/foos
than it does for /api/foos/123
, and so they arrive out of order. This puts my app into an incorrect state, and I would like to fix this, by ensuring that the model
hook for FooBarRoute
is fired only after the promise returned by the model
hook for FoosRoute
has resolved.
How can I do this?
These JsBins provide a concise demonstration of the problem, forked off the demo put together by @kingpin2k:
Using find
. Both models load, but child route loads its model before parent route:
Using fetch
. Both models load, and child route correctly waits for parent route to load model, but UI doesn't update:
You need to use fetch
as we already discussed, and in your custom find
overload you need to return the record, not the results of record.load
which is undefined.
return App.AppModel.fetch(1);
App.AppModel.adapter = Ember.Adapter.create({
find: function(record, id) {
//instead of jQuery.ajax, use ic.ajax as suggested by stefanpenner
//See: https://github.com/emberjs/ember.js/issues/4442#issuecomment-36207354
var req = ic.ajax.raw({
type: 'GET',
url: App.apiUrl+'/appmodels/'+id,
contentType: 'application/json',
dataType: 'json',
processData: false
});
return req.then(function resolve(result) {
console.log('AppModel adapter find resolve', result.response);
record.load(id, result.response);
return record;
});
}
});