jhudson8 / backbone-query-parameters Goto Github PK
View Code? Open in Web Editor NEWBackbone plugin which provides query parameter support
License: Other
Backbone plugin which provides query parameter support
License: Other
In Backbone 0.9.0 hashStrip variable was removed, so it can no longer be used in plugin getFragment method.
Is this plugin still maintained?
Backbone.history
provides a property called fragment
which is normally used to obtain the current fragment to, for example, build <a>
links. I'd like to suggest backbone-query-parameters
add to this by providing the current route/fragment and the current parameters as a separate property, ie.
#foo/bar?a=1&b=2
becomes {fragment: "foo/bar?a=1&b=2", route: "foo/bar", params: {a: 1, b: 2}}
The reason I'm suggesting this is because I have a method in my router called buildFragment
that allows you to build a URL fragment based on the current params:
,buildFragment: function(route, add, preserve) { var newParams = preserve !== undefined && preserve.length && this.params !== undefined ? _.extend(add, _.pick(this.params, preserve)) : add; return (route || this.route) + ( ! _.isEmpty(newParams) ? "?" + $.param(newParams) : ""); }
This allows me to build a URL by adding a parameter and preserving any existing ones I'd like to keep.
For my case, I'm setting the route
and params
property manually on every route, but it would seem like this should be set automatically. Let me know if you know of a better way to do this.
I have this route regex,
this.route( /^!?/?((?:[0-9])+-(?:[0-9a-z-]+))(?:/((?:[0-9])+-(?:[0-9a-z-]+)))?/d/((?:[0-9])+-(?:[0-9a-z-]+))/?(i\d+)?/?([?]{1}.*)?/, 'dealPageAction');
the expected url is /21-texthere/d/4553-55-text-here and when I added backbone.queryparams.js I got an error in line 142: Uncaught TypeError: Cannot read property 'length' of undefined
I'm using backbone 1.0
The params
object is always empty under the new version of Backbone (0.9.9).
When using a query string submitted by an HTML form, all spaces (" ") are converted to "+" and all "+" are converted to "%2B". When the parameters get to the backbone router, all the "%2B" have been converted to "+", but all the "+" have NOT been converted to spaces (" "). At that point we can no longer tell the difference unless we compare it to the original query string.
I prefer to write my query strings with semicolons instead of ampersands. The W3C recommends that web servers (or any query string parser) support semicolon-separated parameters:
http://www.w3.org/TR/html4/appendix/notes.html#h-B.2.2
-var keyValues = queryString.split('&');
+var keyValues = queryString.split(/[&;]/);
Adding support for generating query strings with semicolons would require an interface change, and I care about that less.
the regex for hasQueryString is not matching odata parameter names
e.g. example.com/thing?$filter=whatever
hasQueryString = /(?)[\w-]+=/i
$ is not matched as part of [\w-]
adding it [\w-$] makes it work
I started writing a pull request, but on my machine there are a few failing tests which scared me off ...
Would you like one? the change seems trivial, but the often do :)
thanks for your hard work, Ant
Can you support for ascii value of & in the hash
This returns
topic: Training
type: Reports
IE8 is choking on the ES5 map function on line 96: 'Object doesn't support this property or method'
rtn.paramNames = paramNames.map(function(name) { return name.substring(1); });
It will probably fail on indexOf as well, but I already had a shim in place for that. The plugin can be fixed in IE8 by adding an ES5 shim/polyfill or by defining each of those functions. Here is a good shim: https://github.com/kriskowal/es5-shim
It seems acceptable to have to add a shim for old browsers but some advance warning would be helpful.
Great looking plugin. I just want to suggest a little bit of documentation in the readme.
If you want to use this plugin with regex routes you'll need to append the query capture component (([\?]{1}.*)?
) manually.
router.route(/foo\/([^\/]+)\//, 'foo:event', callback)
should be written
router.route(/foo\/([^\/]+)\/([\?]{1}.*)?/, 'foo:event', callback)
I have a backbone application with 2 routers and am using hash based routing in both. In my first router, query params works as expected and is served from the following url: /app
My second router is served from a url in a nested path: /app/reservation.
For some reason query params works as expected in the first instance but breaks in the second instance with the nested path. Is this expected? Am I missing something?
Params are undifined
getFragment's fragment (the one extended in _.extend(Backbone.History.prototype, { ... })) is without querystring, for example Test/Route insted of Test/Route?foo=bar
E.g. for this url: ?loc%5Blat%5D=10.5&loc%5Blong%5D=-10.5
it returns:
{
'loc%5Blat%5D': 10.5,
'loc%5Blong%5D': -10.5
}
Expected result:
{
loc: {
lat: 10.5,
long: -10.5
}
}
Uncaught TypeError: Cannot read property 'pathname' of undefined
_getFragment()
in source is used both in Backbone.History.prototype.getFragment
and Backbone.Router.prototype.getFragment
, with this
as context. But _getFragment()
contains references to attributes on this
that is only present in Backbone.History
:
Perhaps getFragment()
shouldn't be on Backbone.Router
at all? It really seems like the responsibility of Backbone.History.
function (root, factory) {
if (typeof exports === 'object' && root.require) {
module.exports = factory(require("underscore"), require("backbone"));
} else if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define(["underscore","backbone"], function(_, Backbone) {
// Use global variables if the locals are undefined.
return factory(_ || root._, Backbone || root.Backbone);
});
} else {
// RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
factory(_, Backbone);
}
}
I understand the intention here but it's actually a pretty big issue. 'backbone' and 'underscore' should not be hard coded here as the literal dependency names. The user of the library should be able to manage themselves the importing of a '_' library, in my case I use lodash over underscore, and 'backbone' themselves. Also, people may name 'underscore' or 'backbone' different things so it may cause an additional issue there.
Hello!
When upgrading to 1.1.0, query params is undefined in handler function, when using navigate
method with query params.
I noticed bower.json is at 0.3.1 but there is no release for it. Can you add a release for 0.3.1 so I can properly include it in my bower.json? Thanks!
Does this work with pushstate Router?
Tried it get working, didnt seem to work and I didn't see it in the docs.
Thanks.
I'm curious, why do you destroy the URL params from the URL instead of preserving them until the page navigation?
I can't figure out how to clear query strings. If I am at /resource?foo=1
and I navigate to resource?bar=1
then foo
is removed any the routing works as expected. If I am at /resource?foo=1
and I navigate to /resource
then nothing happens.
Config is done but @jhudson8 needs to enable the tests within the travis UI.
Hi there,
I am running the latest dev version of backbone.js (needed for other patches on HEAD, that are not on 0.9.2), and for the life of me cannot get backbone.queryparams.js to work. It is included after backbone.js is included, and I have jQuery 1.8 on the site.
Has anyone else managed to get this combination working?
routes: {
'index': 'index'
}
index: function(params) {
console.log(attributes);
}
When I open http://example.com/index?foo=bar
I expects params
should be:
{
foo: 'bar'
}
but actually params
is undefined.
console.log
call returns:
["", {foo: 'bar'}]
Hello!
I just try new optional url params #37 .
But with Backbone.Router.namedParameters = true;
parameter names broken. They arrived with parenthesis in names
Since Backbone version 1.1.1 there is support for query parameters.
http://backbonejs.org/#changelog
Do you think it's a good idea that this should be noted in the docs?
Hi jhudson8,
Could you please add a license block/file?
Thanks!
At least I cannot get it to work.
Wattpad's fix works.
Reproducable in iOs 5.1.1 (Safari) and any default Android browser 4+. When browser loads data from back-forward cache (http://stackoverflow.com/questions/11979156/mobile-safari-back-button) an exception is thrown Uncaught TypeError: Cannot call method 'indexOf' of undefined http://abc.com/js/libs/backbone.queryparams.js:30
where line 30 is if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
Hi,
We are using an older version of backbone, version 0.9.2. This plugin looks like a good fit to solve our ULR query param issues. We are stuck on this version until we have a supported effort to upgrade our stack.
I forked your repo and backported the plugin to support 0.9.2. I'm not sure if this is of interest to anyone, of if there was interest in somehow folding it back into the main repo, but I just wanted to put it out there.
I think this behaviour should change from ?cmpid โ {}
to ?cmpid โ {cmpid: ""}
. Unfortunately I see there's already a test that explicitly checks that it decodes to {}
. What was the rational here? It seems like unnecessary data loss to me.
In my application ?cmpid
and ?cmpid=
should be treated equivalent, and I think this makes sense as general rule. Perhaps as part of #14 this behaviour should have been updated too.
Any thoughts on objects nested within arrays?
router.toFragment('somePath', { anArray: [ { a: 'b', c: 'd' } ] }
I started to write a test for this, but realized I had no idea how it should be parsed. You could do
`somePath/anArray=|a=b&c=d'
but that would be the same as
route.toFragment('somePath', { anArray: [{ a: 'b' }], c: 'd' });
I'm not should where else to go from there. Any thoughts?
The README mentions "has been updated to support 0.9.9", which makes me concerned that it doesn't support Backbone 1.0.0. It'd be nice if this was more clear :)
Consider the URL /foo/#/bar/?baz=qux
. In IE this is stripped down to /bar/
. It's my understanding that the correct behaviour should result in /bar/?baz=qux
.
It becomes a little messier for the URL /foo/?abc=def#/bar/?baz=qux
. I think in this scenario it should result in /bar/?baz=qux
.
I have tried out this plugin,
routes: {
"workspaces/:id/library": "index"
},
index: function(route, params) {
console.log(params);
}
I expect: that params should include the query params in the params object
I get: that the query params are on the params object, but under a key "undefined"
For example:
This strikes me as a poor namespace to place the query params under. However, maybe I'm setting this up wrong. Is this the expected behaviour of this plugin?
Not sure if I'm doing something wrong but I'm getting
this.location is undefined on line 45:
45 _fragment += this.location.search;
I changed it to for a quick fix, not sure what the actual scope of that function should be:
45 _fragment += window.location.search;
I was on Backbone 0.9.2 then upgraded to 1.0.0 and encountered the same problem on both.
After going to a page with query params, I do:
Backbone.history.navigate('/something', true);
And the query params still stays in the URL bar. How do I clear it?
The query string ?foo=bar=baz
will be decoded incorrectly to {foo: "bar"}
.
Hello!
I would like to use such route
{route: "u/:user/:section", handler: "userPage"}
But :section
is optional. I using Backbone.Router.namedParameters = true
to get optional params if needed.
But, I don't know how to make some params optional in Backbone.queryparams. In Express it defines like this:
app.get('/u/:login?/:section', function (){});
When an object has an array value which contains a string it will throw an error.
If arrays as arguments for objects is going to be supported there may need to be more checks than just the one I added after the date check.
if(_.isNumber(param)) {
return param.toString();
}
After this fix, the library handles things like foo.bar=|5|6|4&foo.baz=|Me|Too just fine, which is great.
When I copy and paste a URL like http://domain.com?my_ids=1|2|3
, the server errors out. Is it something I need to configure on my end so that webrick error? What do you suggest?
Here's the error:
Bad Request
bad URI `/?hey=1|3'.
WEBrick/1.3.1 (Ruby/1.8.7/2011-06-30) at palawan.local:3000
When using optional path parameters with Backbone.Router.namedParameters = true, the extracted parameter name includes the trailing ')' or the starting '(' of a subsequent optional paramter.
The problem can be solved by changing the namedPattern regexp from
/:*/g to /:*/g
All tests pass after the change (except test 263, which was failing anyway).
Should I make a pull request, considering that the change is extremely simple?
When a date parameter is sent to the toFragment method it fails.
Inside _toQueryParam if the param is a date is calls param.getDate().getTime();
.getDate() will not return a Date object, so I suggest we get rid of it.
if (_.isDate(param)) {
return param.getTime();
}
I.e. foo?bar=1#bat?baz=2
should have bar
and baz
merged into the appropriate destination parameters.
There is a sligh issue when trying to map paramNames on IE -8. Native map supports only from IE9. The fix would be to use underscore map instead of native map.
rtn.paramNames = _.map(paramNames, function(name) {
return name.substring(1);
});
When including the Backbone.queryparams plugin, the routes defined using optional segment stoped being triggered, here's a route example:
"myroute(/:optional)"
Removing the pluging re enable this backbone router feature.
Simply returns undefined
First of all, congratulations for the awesome work! This plugin doesn't work in browserify because backbone and underscore aren't exposed as browser globals. Any chance to fix this?
Hi,
I just came across an issue when working on making our search pages indexable by Google. We use backbone-query-parameters to render search-result pages.
The issue is that Googlebot always encodes the following characters found in URLs: " (space)", "<", ">", "[", "", "]", "^", "`", "{", "|", "}". (read more here: http://www.monperrus.net/martin/google+url+encoding)
Since backbone-query-parameters uses "|" as separators, Google encodes those characters when crawling the URLs (i.e. %7C) and as a result backbone does not render the page as it should be.
I propose adding the following line 214 of backbone.queryparams.js:
var value = Backbone.Router.decodeURISeparator?decodeURIComponent(value):value;
and add the Backbone.Router.decodeURISeparator mention to readme.md.
Let me know your thoughts.
thanks,
Jonathan
This would be great if the project was also published on NPM so we could utilize this in browserify builds. Searched for it but was not able to find it. If it's not published can we add commonjs functionality and publish it to the registry?
Thank you!
Using the example in the readme:
Backbone.Router.prototype.toFragment('myroute', {
a:'l', b:{c: 'n', d:'m', e:{f: 'o'}}, array1:['p'], array2:['q', 'r'], array3:['s','t','|']
});
This throws an error:
line 215 - TypeError: val.replace is not a function
I confirmed this problem exists in my app the moment I tried to convert an array.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.