BACKBONE- ROUTERS
- development
- javascript
- backbone.js
Defined routers should always contain at least one route and a function to map the particular route to. In the example below, we are going to define a route that is always called.
Optional Routes
Search route with query and optional page parameter is an optional route.
var TodoRouter = new (Backbone.Router.extend({
routes: {
'search/:query': 'search',
'search/:query/p:page': 'search',
},
search: function (query, page) {
page = page || 0;
console.log(query);
console.log(page);
},
}))();
Results:
TodoRouter.navigate('search/milk', { trigger: true });
This will print "milk", 0
TodoRouter.navigate('search/milk/p2', { trigger: true });
This will print "milk", 2
Note the duplicate routes are highlighted. We can resolve this issue with an optional route:
var TodoRouter = new (Backbone.Router.extend({
routes: {
'search/:query /p:page ': 'search',
},
search: function (query, page) {
page = page || 0;
console.log(query);
console.log(page);
},
}))();
What if we want to match ‘search/milk/p2/’?
var TodoRouter = new (Backbone.Router.extend({
routes: {
'search/:query (/p:page)(/) ': 'search',
},
search: function (query, page) {
page = page || 0;
console.log(query);
console.log(page);
},
}))();
We can use an optional trailing slash (/)
URI with Spaces
What if the URI you provide has encoded spaces?
To doRouter.navigate('search/Hello%20World/p2', {trigger: true})
You will get the following result, which is not decoded:
"Hello%20World", 2
var TodoRouter = new (Backbone.Router.extend({
routes: {
'search/:query (/p:page)(/) ': 'search',
},
search: function (query, page) {
page = page || 0;
query = decodeURIComponent(query);
console.log(query);
console.log(page);
},
}))();
The result will be decoded:
"Hello World", 2
Regex in Routes
Say we want to restrict parameter to numeric input, let's see how can achieve this:
var TodoRouter = new (Backbone.Router.extend({
routes: {
'todos/:id': 'show',
},
show: function (id) {
console.log('id = ' + id);
},
}))();
TodoRouter.navigate('todos/2', {trigger: true})
Result: id = 2
TodoRouter.navigate('todos/notanid', {trigger: true})
Result id = notanid
So this shouldn’t trigger show.
var TodoRouter = new (Backbone.Router.extend({
show: function (id) {
console.log('id = ' + id);
},
}))();
TodoRouter.route(/^todos\/(\d+)$/, 'show');
Here each Regex Capture Group becomes a param.
TodoRouter.navigate('todos/2', { trigger: true }); // id = 2`
TodoRouter.navigate('todos/notanid', { trigger: true });
This doesn't trigger show.
var TodoRouter = new (Backbone.Router.extend({
initialize: function () {
this.route(/^todos\/(\d+)$/, 'show');
},
show: function (id) {
console.log('id = ' + id);
},
}))();
This keeps routes inside the router.
Advanced Regex Routes
Let's examine this advanced route formation:
/^search\/(\w+)(?:\/p(\d+))?\/?$/ --> 'search/:query(/p:page)'

This router matches:
'search/milk';
'search/milk/p2';
'search/milk/p2/';
But it doesn't match the following:
'searches/milk';
'search/milk/p2/p1';
'search/milk/2';
Catch-all Routes
Alert user when no route matches:
var TodoRouter = Backbone.Router.extend({
routes: {
'*path': 'notFound',
},
notFound: function (path) {
alert('Sorry! There is no content here.');
},
});
TodoRouter.navigate('nothinghere', { trigger: true });
This will result in:

File Path Route
Accept a file path and get its parts
var TodoRouter = new (Backbone.Router.extend({
routes: {
'file/*path': 'file',
},
file: function (path) {
var parts = path.split('/');
console.log(parts);
},
}))();
TodoRouter.navigate('file/this/is/a/file.txt', { trigger: true });
Result:
[" this", "is", "a", "file.txt"]
If you want to learn about more follow my other articles on Backbone here: