8

Is there any method to detect invalid (or undefined) route and trigger 404 page in Backbone.Controller?

I've defined routes in my Controller like this, but it didn't work.

class MyController extends Backbone.Controller
    routes:
        "method_a": "methodA"
        "method_b": "methodB"
        "*undefined": "show404Error"

    # when access to /#method_a
    methodA: ->
        console.log "this page exists"

    # when access to /#method_b
    methodB: ->
        console.log "this also exists"

    # when access to /#some_invalid_hash_fragment_for_malicious_attack
    show404Error: ->
        console.log "sorry, this page does not exist"

UPDATE:

I used constructor of Backbone.Controller to match current hash fragment and @routes.

class MyController extends Backbone.Controller
    constructor: ->
        super()
        hash = window.location.hash.replace '#', ''
        if hash
            for k, v of @routes
                if k is hash
                    return
                @show404Error()

    routes:
        "method_a": "methodA"
        "method_b": "methodB"
        "*undefined": "show404Error"

    # when access to /#method_a
    methodA: ->
        console.log "this page exists"

    # when access to /#method_b
    methodB: ->
        console.log "this also exists"

    # when access to /#some_invalid_hash_fragment_for_malicious_attack
    show404Error: ->
        console.log "sorry, this page does not exist"
David Murdoch
  • 87,823
  • 39
  • 148
  • 191
tomodian
  • 6,043
  • 4
  • 25
  • 29
  • If you have solved your own problem then answer your own question. – Raynos Jun 27 '11 at 12:18
  • 2
    Suggestion is to rewrite your question so that it only contains the question and then provide your own answer. So, omit the answer in the question. You may find that someone has a better way to answer your question if you don't immediately provide the answer. – Bill Eisenhauer Jun 27 '11 at 14:14
  • Yes, your suggestion is right. Thank you for sharing about it! – tomodian Jun 30 '11 at 04:21
  • 1
    Also don't put solved in the answer – andho Nov 11 '11 at 12:58

1 Answers1

10

The above works, but I'm not sure why you have to do what you do in the constructor. It may be slightly brittle, but we create a separate controller that we include in last. Its last so that the splat route is the last one to match:

NotFound = Backbone.Controller.extend({

  routes: {
    "*path"  : "notFound"
  },

  notFound: function(path) {
    var msg = "Unable to find path: " + path;
    alert(msg);
  }

});

new NotFound();

Using a more robust version of the above seems a cleaner approach to me.

Bill Eisenhauer
  • 6,183
  • 2
  • 30
  • 28
  • I am Backbone newbie, and wanted to use Rails before_filter-like approach, which triggers before running Controller's method. But your solution also seems robust and cleaner. Thank you! – tomodian Jun 30 '11 at 04:34