Shoaib
Shoaib

Reputation: 561

Default route in Backbone using routes property

I'm working with a Backbone project, and in our router we specify a default route at the end of the routes property:

routes: {
    "things": "stuff",
    "*actions": "default"
}

From a bit of searching around, I've seen a couple of places, such as this StackOverflow answer and the Backbone tutorial, which suggest adding a default route this way.

However, this deeply concerns me, because from what I can see in the Backbone source, the routes property is simply iterated over to add all the routes in it, and to the best of my knowledge, object iteration in JavaScript doesn't guarantee any ordering. Therefore, with the above routes definition, it's not guaranteed that the default route has lowest precedence just by virtue of being at the end of the definition.

Is the behavior essentially undefined here, and things are actually working out just a matter of pure luck, or is there something else going on that actually makes this a safe thing to do?

Upvotes: 3

Views: 159

Answers (1)

machineghost
machineghost

Reputation: 35790

As you identified, routes derived from the route property have no guaranteed order ... although in practice many browsers will iterate through them in the order defined, and you could also guarantee the order by using the route method instead.

But what about those two examples you linked? Well, if you look carefully at them, you'll notice they don't have any other routes at the same level the way you do. The splat syntax exists simply to a provide more readable way of writing "anything that's not a question mark" (ie. ([^?]*?)); it's not actually meant to be a default handler.

So, if what you're trying to achieve is:

if (url == 'things') {
    doStuff();
} else {
    doActions();
}

you have two choices. If you're willing to change your url structure you can simply have:

/things
/actions/*actions

If you're not, you just need to define a route that differentiates:

routes: {':rootLevelPath': rootLevelPathRoute},
rootLevelPathRoute: function(rootLevelPath) {
    if (rootLevelPath == 'things') {
        doThings();
    } else {
        doActions();
    }
}

Upvotes: 1

Related Questions