Search code examples
regexbackbone.js

Backbone route _extractParameters capturing an extra null parameter


I have the following route in my Backbone router:

'surveys/:surveyId?:opts': 'SurveyList:Selected'

And the following handler that captures any route and republishes it on a message bus for my views to handle:

this.on('route', function() {
    PubSub.publish(Events.RouteChanged, {
        route: arguments[0],
        options: arguments[1]
    });
});

When the router matches the route surveys/myTestId123?pageNum=2, the expected behaviour is that arguments[1] would be an array of 2 arguments: myTestId123 and pageNum=2. However, it is actually an array with 3 arguments - the two aforementioned ones and a null value as the third. I narrowed this down to the _extractParameters method, which matches the url fragment against a regular expression. In this case, the regular expression is /^surveys\/([^\/?]+)(?:\?([^\/?]+))?(?:\?([\s\S]*))?$/i.

Interestingly enough, I get the correct parameters when the route is surveys/:surveyId, which in turn produces this regex: /^surveys\/([^\/?]+)(?:\?([\s\S]*))?$/i.

Here is a fiddle showing the problem in action.

Is this a problem with the regex that Backbone creates from my route, or a problem with the route itself?


Solution

  • I think I've just discovered the answer. It looks like Backbone already does what I'm trying to do. If I have the route surveys, it also provides a null parameter. However, the regex it creates is as follows:

    /^surveys(?:\?([\s\S]*))?$/i
    

    This appears to already match querystring parameters, which explains why the shorter route works in my example above. Those clever people at Backbone were one step ahead of me.

    Update:

    From the Backbone v1.1.1 change log:

    Backbone Routers now handle query params in route fragments, passing them into the handler as the last argument. Routes specified as strings should no longer include the query string ('foo?:query' should be 'foo').