navigate route with querystring
Solution 1
You need to add another route with that expecting parameter :
routes: {
'posts?foo=:foo' : 'showPosts',
'posts': 'showPosts'
},
showPosts: function (foo) {
if(typeof foo != 'undefined'){
// foo parameters was passed
}
test = true;
}
update
You could define the general route to return all the query string and then parse it in the handler :
routes: {
'posts': 'showPosts',
'posts?*queryString' : 'showPosts'
},
showPosts: function (queryString) {
var params = parseQueryString(queryString);
if(params.foo){
// foo parameters was passed
}
}
...
// and the function that parses the query string can be something like :
function parseQueryString(queryString){
var params = {};
if(queryString){
_.each(
_.map(decodeURI(queryString).split(/&/g),function(el,i){
var aux = el.split('='), o = {};
if(aux.length >= 1){
var val = undefined;
if(aux.length == 2)
val = aux[1];
o[aux[0]] = val;
}
return o;
}),
function(o){
_.extend(params,o);
}
);
}
return params;
}
update 2
Here's a live demo to see the code in action.
Solution 2
Just to complement the previous answers, instead of defining two routes that have the same callback, like:
routes: {
'posts': 'showPosts',
'posts?*querystring': 'showPosts'
}
You could have only one route to keep the code cleaner:
routes: {
'posts(?*querystring)': 'showPosts'
}
Solution 3
Backbone docs:
Routes can contain parameter parts, :param, which match a single URL component between slashes; and splat parts *splat, which can match any number of URL components.
If you still want to keep the functionality without the matching you can define two routes
routes: {
'posts': 'showPosts',
'posts?*querystring': 'showPosts'
}
showPosts: function(querystring) {
if (querystring) {
// here you can parse your querystring, for your case the querystring variable is
// 'foo=3'
}
//here you'll show posts according to the querystring (or lack thereof)
}
Solution 4
Here's another take, still using lodash (underscore). Removed the _.map, added a bit of verbosity to the variables, and stripped out the starting '?' if present:
function parseQueryString(queryString)
{
if (!_.isString(queryString))
return
queryString = queryString.substring( queryString.indexOf('?') + 1 )
var params = {}
var queryParts = decodeURI(queryString).split(/&/g)
_.each(queryParts, function(val)
{
var parts = val.split('=')
if (parts.length >= 1)
{
var val = undefined
if (parts.length == 2)
val = parts[1]
params[parts[0]] = val
}
})
return params
}
Solution 5
RFC 3986 "syntax for URIs" states that query parameters shold come before hash fragment.
In URIs a hashmark # introduces the optional fragment near the end of the URL. The generic RFC 3986 syntax for URIs also allows an optional query part introduced by a question mark ?. In URIs with a query and a fragment, the fragment follows the query.
I have this issue handling a redirect I am getting from the server i.e. "http://foo.com/main.html?error=errormessage#site". I would like to route on the query but can't see a way to write the backbone route expression to handle this url. For now I just route on the hash and check for a query by parsing location.search.
abernier
Hi, I'm Antoine Bernier — JS fullstack webdev with 15y of experience. I love animation, unix, design and opensource. Feel free to contact me 👋 http://be.net/abernier
Updated on February 14, 2020Comments
-
abernier about 4 years
Will
Backbone.Router.navigate
settest
totrue
:var test = false; var Router = Backbone.Router.extend({ routes: { 'posts': 'showPosts' }, showPosts: function () { test = true; } }); router = new Router(); Backbone.history.start(); router.navigate('posts?foo=3', {trigger: true}); assert.ok(test);
Eg, will
posts?foo=3
fragment will match theposts
route by default, or do I have to set another route for that, for example:posts?*querystring
?Thank you
PS: I know there exist the backbone-query-parameters but I want to know just for backbone.
-
abernier almost 12 yearsIs
?*
without a name for the splat?*querystring
ok? -
abernier almost 12 yearsIn one case you define the most specific route (
posts?foo=:foo
) first, and on the other case on second position: doesn't order matter? -
gion_13 almost 12 yearsno , it doesn't affect how routes are being applied. It's just a matter of preference. BTW, I've tested & updated the function and now it works great.
-
Daniel Birowsky Popeski almost 11 yearsIs this supposed to work in Backbone 1? Cz it's not triggering any route action after I added the '?*query'
-
jakee almost 11 yearsThe answer was made almost a year ago. But the docs or changelogs don't hint towards any reasons for this not to work
-
kinakuta over 10 yearsI'm having the same problem. Having a route with ?*queryString not only doesn't capture the queryString variable, but if I have this and not the route without the query string, the route doesn't get interpreted at all.
-
kinakuta over 10 yearsI see this demo working, but for reasons I still cannot fathom, this does not work for me. Using these route constructions, queryString is always undefined.
-
kinakuta over 10 yearsI see what the issue is - while you're able to execute the route by passing true to navigate, this still doesn't not work with history correctly. Additionally, having to pass true to navigate is less than ideal as it requires my router execute navigation rather than simply executing interpreted routes.
-
abernier about 10 yearsThis answer is getting far from the initial question... Your answer is now more a how to parse a querystring...
-
Mark Robson almost 10 yearsThis works only when triggering Router.navigate('posts?foo=bar',{trigger:true,replace:true}); with replace:true. Is there a way for it to work when you go directly to the url?
-
azz0r over 9 yearsThanks for this, should have got more attention imo
-
Luis almost 9 yearsMatching on the whole query string does not work when you are using URI encoded query parameters (e.g. "foo=Max%20%26%20Moritz") because backbone.js only expects full path fragments and already calls decodeURIComponent on every route parameters. Therefore parsing the query string later will not work correctly.
-
Luis almost 9 yearsMatching on the whole query string does not work when you are using URI encoded query parameters (e.g. "foo=Max%20%26%20Moritz") because backbone.js only expects full path fragments and already calls decodeURIComponent on every route parameters. Therefore parsing the query string later will not work correctly.