Ember.JS: How to handle invalid URLs

There’s a lot of documentation for the new Ember Router. However, I found that no one was talking about how to handle the “*” route in Ember, i.e. the routes that don’t match anything.

I first tried to look at the ApplicationRoute but that didn’t seem to throw anything. Ember just sits there with a lovely blank page!

ApplicationRoute { 
events: {
errors: function(reason, transition) {
console.log("never happened");
}
}
}

So here’s the easiest solution for handling bad urls. My router looks like this now:

App.Router.map( function() {

this.route('login');
this.resource('companies', {path: 'companies'});
this.resource('company', {path: 'companies/:company_nice_url'}, function() {
this.route('members');

});



this.route('bad_url', { path: '/*badurl' }); // Catch everything else!

});

The last route named “bad_url” will catch all the other unrecognized URLs and direct the user to the App.BadUrlRoute where you can handle them. You will get the URL segment as params.bad_url for you to inspect and offer friendly advice like “hey did you mistype companies?”.

If you simply want to show a page that says “There’s no one here you fool!”, just create a handlebars template:

<script type="text/x-handlebars" data-template-name="bad-url">
<h1>There’s no one here you fool!!!!</h1>
</script>

And you’re done! Any path that doesn’t match your routes will get routed through ‘bad-url’, where you can act on it accordingly.

 

EDIT ON 6TH AUGUST

Marcus in the comments pointed out to me that using path: ‘/*badurl’  is better due to this handling /this/is/wrong/path” situations. My initial solution to using a dynamic segment (:bad_url) did not catch this. Thanks to all the commenters!

 

EDIT ON 7TH AUGUST

I have realised that having “*badurl” instead of “:bad_url” has one caveat. I am implementing a funky search route that deals with all URLs past a base route like this: /search/x/y/z/a/b/c . Having the astriks to catch all the bad url’s makes it impossible to have a search router which deals with “/search/*search_terms“. So there you go… ups and downs to both methods. More on that awesome search route another day… 🙂

 


Comments

8 responses to “Ember.JS: How to handle invalid URLs”

  1. Marcus Böhm Avatar
    Marcus Böhm

    Have you also considered using the following?

    this.route(‘missing’, { path: "/*path" });

    I saw it once posted by wagenet on Twitter. Have used it since and it worked out so far.

    1. Juarez P. A. Filho Avatar
      Juarez P. A. Filho

      Nice post Dineth, but I think the Marcus solution is simpler and very simple to implement, in fact I just put in my code this route with missing and it’s working like a charm. 😀

    2. Jason Kriss Avatar
      Jason Kriss

      Yea, I believe using the wildcard ‘*/path’ is the better way to go. If you use the dynamic ‘:/:path’, then it will only catch invalid segments. That is, it will work if you hit ‘/invalid’, but break if you hit ‘/invalid/url’. The wildcard approach handles both of these.

    3. Dineth Mendis Avatar
      Dineth Mendis

      Thanks Marcus!! That is an excellent tip. Not sure why it isn’t in the doco. I am going to give it a spin on my Ember app this morning and update my post accordingly. Thanks for pointing out the better solution. Awesome!

    4. Dineth Mendis Avatar
      Dineth Mendis

      I’ve changed the post to reflect your superior solution! I did note that the backslash was not required to make it work. Thanks again.

  2. Andy Matthews Avatar
    Andy Matthews

    How would you handle URLs that are valid, but return a 404 because a record was deleted?

    For example:

    /accounts/64

    1. If you are using the newest version of Ember (1.2 beta4), when your model rejects from a server error like that, it will bubble through the "error" actions handler. For example, in your ApplicationRoute you can have:

      actions: {
      error: function (reason, transition) {
      if (reason.status === 404) { //handle the error }
      }
      }

  3. Er Samrow Avatar
    Er Samrow

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *