New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strip fragment's search params before route matching in loadUrl #2126
Conversation
Thanks for the patch @mclin! It's failing the tests though, and I'm not sure about this approach. If you want to ignore the search parameters, why do you need them in the url? Also, if the browser is using pushState then |
Hey, sorry. Didn't really mean this as a patch. Just wanted to show you what I meant. I'll look into how to run the tests. I want to ignore the search params only when matching against routes, the same way that rails routing ignores search params. But search params should accessible in the route handler, also same as rails, either as an extra param to the route handler or directly from window.location.search. The url and the search params serve different purposes. The url identifies which resource you want (and hence which handler). The search params affect how it's queried (eg filter/sort/pagination) or how it's displayed (eg which tab in a tab view to show). I've only used backbone with pushState on, I'll see how this would affect hash based routing. |
@mclin For future reference, on GitHub, if you just want to show a diff you can use the diff --git a/backbone.js b/backbone.js
index 25ce414..bdd90f8 100644
--- a/backbone.js
+++ b/backbone.js
@@ -1026,6 +1026,7 @@
// Cached regex for stripping a leading hash/slash and trailing space.
var routeStripper = /^[#\/]|\s+$/g;
+ var searchStripper = /\?.*$/g;
// Cached regex for stripping leading and trailing slashes.
var rootStripper = /^\/+|\/+$/g;
@@ -1158,6 +1159,7 @@
// returns `false`.
loadUrl: function(fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
+ fragment = fragment.replace(searchStripper, '');
var matched = _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment); and GitHub will color it up nicely. |
@caseywebdev Good tip! |
@caseywebdev The more you know. Thanks! |
+1, this would be very helpful. |
…hing. extract and parse search params in _extractParameters
Got all the tests passing. Also made it parse the search params in _extractParameters and pass them in the last param to the route handler as an Object. |
This is very important patch. I still waiting for it! Hope soon to be merged. |
I've read the discussion in #891 and I believe this is a better way to do it. But in my opinion, it's not Backbone's job to parse the search params and push it into the extracted parameters for the matched routes. Maybe we can just add a |
+1, this is very similar to changes we've implemented minus the parameter parsing (would be handy, but I can see the argument against it not being Backbone's job). |
Hey, I see your point about not parsing the search string, so I took it out. |
@mclin 👍 That's better :)
And this is the reason against the extra parameter
The 2nd param in the |
+1 for it.. I'm facing the same problem of route matching when there is search query appended in url, this pull solved my problem and I hope it will be soon at master |
just noticed that when backbone.js first load no query string is placed inside History fragment getFragment: function(fragment, forcePushState) {
if (fragment == null) {
if (this._hasPushState || !this._wantsHashChange || forcePushState) {
fragment = this.location.pathname; as you can see, getFragment method is ignoring if there is no fragment parameter passed inside the function (the case when you first load your app)... my solution is simple and its working for now as a workaround fragment = this.location.pathname + this.location.search; |
Hey @mateusmaso, that change is already in this diff. |
+1 Seems like the intuitive thing to do. |
@braddunbar -- do you consider this PR to supersede yours? Let me know. |
Backbone shouldn't be messing with the search params, as they don't have a valid semantic meaning from the point of view of a Backbone app. If you want to use them (on a page that has a running backbone app), that's totally fine ... but you don't need to pass them to
|
@jashkenas is the expected behavior in 1.0.0 that router.navigate will ignore question marks and anything following them? For example, should I'm finding this to be the case when doing a complete page reload, but not when triggering a route change with pushState. |
Mornin' @hitchcockwill! No, |
@braddunbar thanks for the reply. Is it expected that |
That's right, |
Is there a reason that the router behaves like this? I know that this has been a topic of debate over the last few months, but the current solution seems half-baked. If the sentiment is that Backbone should ignore query parameters, then shouldn't Backbone.History and the Router#navigate function both act in the same way? |
Check out #891 for some background. It holds most of the conversation surrounding search params and the problems surrounding them. As for |
This is based on discussion with @braddunbar in #891
Based on my description he made this change: #2122
But that prevents the search params from getting into the history/url bar.
Here, just strip the search params for the purpose of route matching only.