I've recently been porting a number of Ember apps I maintain to RC 8 and ran into this.
Before the router facelift landed I would sometimes manage control flow via promises returned by Ember Data find
calls.
For example:
SomeRoute = Ember.Route.extend({
model: function(params) {
var resolve = function(model) { return model; };
var route = this;
var reject = function() { this.transitionTo('someOtherRoute'); };
return SomeModel.find(params.some_model_id).then(resolve, reject);
}
...
});
With the recent changes, it is now possible to handle errors created in model callbacks via the error
action:
SomeRoute = Ember.Route.extend({
// note: model callback no longer needed--default suffices
actions: {
error: function(reason, transition) {
// check the reason object to determine how/if to handle this error
this.transitionTo('someOtherRoute');
}
}
...
});
I much prefer the latter approach as it makes the code easier to read and better separates concerns.
This works well in most cases but I encountered an issue in an app that uses nested routes. I've included a simplified example followed by a jsbin that demonstrates the issue.
Lets say we want to show Article
s that belong to Author
s and the URLs look like: /authors/:author_slug/articles/:article_slug
. We want to redirect to a Not Found page when someone tries to view an article that doesn't exist.
When managing control flow in the model
callback as above, you can browse to /authors/some_author/articles/some_invalid_slug
and be redirected to /authors/some_author/articles/not_found
as expected.
However, if the redirect to the Not Found page is instead managed via the error
action, the parent context is lost at some point and you end up at /authors/undefined/articles/not_found
.
You can see this in the following jsbins:
http://jsbin.com/eJOXifo/1#/authors/schneier/articles/12345 (redirects to http://jsbin.com/eJOXifo/1#/authors/schneier/articles/not_found)
http://jsbin.com/oNaWelo/1#/authors/schneier/articles/12345 (redirects to http://jsbin.com/oNaWelo/1#/authors/undefined/articles/not_found)
Does anyone know why this happens or how to avoid it?
Notes:
- I know this doesn't have anything to do with Ember Data. However, implementing something equivalent without Ember Data just makes the example more complicated without adding anything
- There are a few small hacks to make Ember Data work as expected in jsbin:
- I'm preloading the parent model to avoid having to load it from anywhere.
- I'm not doing anything special to provide data for the child model. The app just makes a request to
http://jsbin.com/articles/12345
. This actually returns a 200 but bombs anyway because the response is html. An API that correctly returns a 404 response gives the same behvaiour. - I remember a while ago reading about some service that could be used to build fake API responses for use with services like jsfiddle or jsbin. If anyone knows what it is please comment.