Ember render 404 with invalid urls
I am using dynamic urls in my app for readability. Url structure /[:organization_slug]/[:product_slug]
. In other words, it organization
is the owner product
. For security purposes, I want to display a 404 when someone enters an organization into a URL when it doesn't exist. Also similarly render 404 when a product that doesn't exist is entered into the url.
I have implemented Ember 404 as described in this post . Then I connect to afterModel
to see if the request returned a record and tried to navigate to the route fourOhFour
if not. Here is my code:
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 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 the transition is not firing. The route is not activated and the template is not displayed. I think this is because the route exists due to the nature of the dynamic url. However, I want to keep the url, but display the 404 template that is not working correctly. If I change path
the 404 route to a static string such as /404
, the transition works. However, I would like to keep the url of the original request, if possible.
This way, if someone asks for a route that doesn't actually exist (i.e. /foo/bar/baz
), it will look identical to the page where the route is valid, but the entry doesn't exist. Can anyone point me in the right direction?
Thanks in advance!
source to share
I believe your problem is that when you try to go to catch all, Ember.js has no idea what it is. This is easy to fix as it transitionTo()
takes a second parameter to specify the model, which in your case will be the URL.
So, for a non-existent product, your route will look something like this:
App.BadRoute = Ember.Route.extend({
model: function(){
return "abcdproduct";
},
afterModel: function(badProduct){
this.transitionTo('notFound', badProduct);
}
});
See a basic working example here
source to share