Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

$location.search() returns empty when query params are not preceded by hash #7239

Closed
nosideeffects opened this issue Apr 24, 2014 · 30 comments
Closed

Comments

@nosideeffects
Copy link
Contributor

www.url.com?query=things
$location.search() === {}

www.url.com#?query=things
$location.search() === {query: "things"}
@caitp
Copy link
Contributor

caitp commented Apr 24, 2014

This is a duplicate of #6198 and #5964 --- we know that this works correctly in html5 mode, but alright, I'll take another stab at fixing this.

Not going to close this since the dupe issues are already closed

@caitp caitp self-assigned this Apr 24, 2014
@caitp caitp added this to the 1.3.0 milestone Apr 24, 2014
@nosideeffects
Copy link
Contributor Author

Thank you kindly!

caitp added a commit to caitp/angular.js that referenced this issue Apr 25, 2014
… mode

This fix causes LocationHashbangUrl#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

Closes angular#7239
@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

@nosideeffects feel free to try that out and see if it works for you. It took a lot of work to get it doing that without breaking it, so it feels very difficult to make this work right in all cases.

caitp added a commit to caitp/angular.js that referenced this issue Apr 25, 2014
… mode

This fix causes LocationHashbangUrl#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

Closes angular#7239
@nosideeffects
Copy link
Contributor Author

It still doesn't appear to work in our app without a preceding hash. I will add preceding hashes in our codebase for now.

Thank you for your extremely quick response and hard work!

@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

It only works for hashbang mode (not html5 mode because iirc there was already a fix for html5 mode, but apparently not).

However, there is a test verifying that it works without a hash

@nosideeffects
Copy link
Contributor Author

What if the query params exist on page load? The following fails:

url = new LocationHashbangUrl('http://server/base', '#!');
url.$$parse('http://server/base?a=b');
expect(url.search()).toEqual({
  'a': 'b'
});

@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

That's because you aren't calling $$rewrite --- but $$rewrite always gets called.

@nosideeffects
Copy link
Contributor Author

Then I am confused by the behavior I am seeing.

$location.absUrl() = "http://local.site.com:8080/login?param=thing"
$location.host() = "local.site.com"
$location.port() = 8080
$location.search() = {}
$location.path() = "" 
$location.hash() = "" 

@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

There's a test case verifying that it works, you might be using the version of the patch from last night before that was added.

Or you might be using html5Mode. Provide a reproduction so I can see for myself

@nosideeffects
Copy link
Contributor Author

What I am saying is that I am currently using your patched build in our app, which I downloaded a little over an hour ago.

The tests pass, but the $location service still doesn't behave as I would expect.

@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

I understand what you're saying, what I'm saying is, post a reproduction

@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

I've reproduced it myself, and I see what you're saying. It's because stripHash() is returning too much of the initial url. Not sure why that works in tests then... I'll fix that

caitp added a commit to caitp/angular.js that referenced this issue Apr 25, 2014
… mode

This fix causes LocationHashbangUrl#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

Closes angular#7239
@caitp
Copy link
Contributor

caitp commented Apr 25, 2014

Okay, fixed

caitp added a commit to caitp/angular.js that referenced this issue Apr 25, 2014
… mode

This fix causes LocationHashbangUrl#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

Closes angular#7239
caitp added a commit that referenced this issue Apr 25, 2014
… mode

This fix causes LocationHashbangUrl#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangUrl would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes #7239
@nosideeffects
Copy link
Contributor Author

Hurray! Thank you so much!

@IgorMinar
Copy link
Contributor

Please take a look at this commit: 3d6dff4

We reverted a similar change in the past because of regressions and overall mismatch with the original design of the $location service.

I realized that this change should however be accepted for the LocationHashbangInHtml5Url mode.

@jimthedev
Copy link

For those having this problem and needing a workaround now. You can use this to get the querystring parameter 'a':

var parseLocation = function(location) {
    var pairs = location.substring(1).split("&");
    var obj = {};
    var pair;
    var i;

    for ( i in pairs ) {
      if ( pairs[i] === "" ) continue;

      pair = pairs[i].split("=");
      obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
    }

    return obj;
  };

  parseLocation(window.location.search)['a']

caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
caitp added a commit to caitp/angular.js that referenced this issue May 2, 2014
…5mlMode

This fix causes LocationHashbangInHtml5Url#$$rewrite() to move a pre-hash query string
to after the hash.

This, in turn, causes urlResolve() to correctly parse the query string, and
report the correct dictionary.

BREAKING CHANGE

Previously, LocationHashbangInHtml5Url would keep query parameters from the initial URL
preceeding a hash symbol as part of the application base url. This is no longer
the case, as it is desirable to parse these as part of the search query.

To migrate, one should create special urls rather than relying on query string,

for instance, if a base url was previously "http://server.com/base?ie=true", it
would be adviseable to instead use "http://server.com/base/ie" as the base url.

Closes angular#7239
@caitp
Copy link
Contributor

caitp commented May 2, 2014

sorry about the commit spam ^-^

@jimthedev
Copy link

Thank you!

@amitport
Copy link

this still happens in angular 1.3

www.url.com?query=things
$location.search() === {}

@albertpeiro
Copy link

Has this gone into 1.3? If not should we expect it? When?
Thank you!

@temp3l
Copy link

temp3l commented Nov 27, 2014

still happens in 1.3.4 (html5mode)

@ryepup
Copy link

ryepup commented Jan 2, 2015

still happens in 1.3.5 (html5mode)

@seiyria
Copy link

seiyria commented Jan 6, 2015

This seems to work in 1.3.8 with html5mode.

@mstrutt
Copy link

mstrutt commented Feb 25, 2015

for me, still happens in 1.3.14 (html5mode)

@ams10961
Copy link

The twitter Oauth call-back inserts a token and verifier in the URL before calling, so

www.url.com/index.html#/callback

becomes

www.url.com/index.html?token=abc&verifier=xyz#/callback

What I'd like is:

$location.search() === {token: "abc", verifier:"xyz"}

what I get is

$location.search() === {}

I assume this is the same problem.

@griffinqiu
Copy link

still has the issue in 1.3.15

+10086

@prettycode
Copy link

+1 still have issue in 1.3.16

When $location.absUrl() is http://localhost:49215/home/Login/?ReturnUrl=%2fvnext#/, and the HTML page has <base href="/" />, $location.search() returns an empty object.

@Ozkee
Copy link

Ozkee commented Oct 27, 2015

for workaround add configuration for module

.config(($locationProvider) ->
$locationProvider.html5Mode({
enabled: true,
requireBase: false
})
)

@emersonthis
Copy link

I'm still having this problem in v1.4.7. @reg1sek 's workaround worked for me.
CORRECTION: I spoke too soon. The workaround makes $location.search() work for me, but prevents all my <a> links from working because html5Mode rewrites them.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.