I'm using dynamic URLs in my application for easy readability. The url structure is /[:organization_slug]/[:product_slug]
. In other words, an organization
is the owner of a product
. For security purposes, I want to display a 404 when somebody types an organization in the URL when it doesn't exist. Also similarly, display a 404 when a product that doesn't exist is entered into the URL.
I've implemented the Ember 404 as described in this post. Then, I'm hooking into afterModel
to see if the query returned a record and trying to transition into the fourOhFour
route if not. Here is my relevant code currently:
router.js
Router.map(function() {
this.route("fourOhFour", {path: "*path"});
this.resource('organization', {path: ':organization_slug'}, function() {
this.resource('product', {path: ':product_slug'});
});
});
routes/organization.js
var OrganizationRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('organization', {slug: params.organization_slug});
},
afterModel: function(organization, transition) {
if(organization.get('length') === 0) {
//If it's not a correct URL render the 404
this.transitionTo("fourOhFour");
}
},
serialize: function(model) {
return {organization_slug: model.get('slug')};
}
});
export default OrganizationRoute;
routes/product.js
var ProductRoute = Ember.Route.extend({
model: function(params) {
var self = this;
// Verify that the product belongs to the organization in the URL
return this.store.find('organization', {slug: Ember.organizationSlug}).then(function(organization) {
var organizationID = organization.get('firstObject.id');
return self.store.find('product', {slug: params.product_slug, organization: organizationID});
});
},
afterModel: function(product) {
if(product.get('length') === 0) {
this.transitionTo("fourOhFour");
}
},
serialize: function(model) {
return {product_slug: model.get('slug')};
}
});
export default ProductRoute;
The problem is that the transition is not firing. The route is not activating and the template is not being rendered. I think this has something to do with the fact that the route exists due to the nature of the dynamic URL. However, I want to maintain the URL path but display the 404 template, which is not working properly. If I change the path
of the 404 route to a static string like /404
the transition works. However, I'd like to keep the URL path of the original request if possible.
That way, if someone requests a route that actually doesn't exist (i.e. /foo/bar/baz
), it will look identical to a page where the route is valid but the record does not exist. Can anyone point me in the right direction?
Thanks in advance!
I believe your issue is that when you are trying to transition into a "catch all", Ember.js has no idea what that is. This is easy to fix as
transitionTo()
takes a 2nd parameter for specifying the model, which in your case would be the URL.So, for a non-existent product, your route would look something like this:
See a basic working example here