When on the url index.html
when I set the hash at some point to, say, "foo=bar"
, the url gets two hashes in it.
So, as part of a click handler or something (doesn't really matter):
$location.hash("foo=bar");
The url becomes:
index.html##foo=bar
But we should expect:
index.html#foo=bar
This is Angular 1.4.8 on Firefox 43 on Windows 10.
Also happens in Chrome 47, IE11, and Edge 13.
You can use
var url = $location.absUrl();
This is due to the fact that the default location mode is html5Mode(false)
, which relies upon using hash-bang style paths. Unfortunately the default hash-prefix is nothing ""
and so we the location service adds in the hash-bang path (i.e. #
) followed by your hash, #foo=bar
.
The simple workarounds are:
$locationProvider.html5Mode(true)
$locationProvider.hashPrefix('!')
, which will result in urls that look like: index.html#!#foo=bar
The differences between html5 and hashbang mode are detailed in the dev guide (in case you haven't read that already).
This pretty much expected behavior.
Are you using client-side routing (e.g. ngRoute
or uiRouter
) ?
@gkalpak - do you think we ought to make a BC in 1.5.0 and change the default hashPrefix
to be "!"
? This would make this less confusing IMO.
@gkalpak I'm not using any type of routing. It's a true singlepage application I'm working on, that just needs to store a search query in the url.
@petebacondarwin Would html5Mode not cause the hash sign to disappear completely? html5Mode usually requires changes at the server level (rewriting urls and stuff) which in our case is not an option... The hashPrefix isn't a real elegant workaround, I hope you agree. I would like to keep the url as elegant as I can with the restriction I mentioned.
If you are not doing routing and you never change the $location.path()
then you don't need any server side support. It will only get rid of the first hash. I would give it a try.
@thany:
It's a true singlepage application I'm working on
_true singlepage applications_ do have client-side routing (unless you mean it's just a single page :smiley:).
just needs to store a search query in the url
Why are you using .hash()
if you want too store a search query ? (Or do you also need the hash in addition to the search query ?)
html5Mode usually requires changes at the server level
If there is indeed no client-side routing involved, then html5 should not need any configuration on the server.
Would html5Mode not cause the hash sign to disappear completely
It would make the 1st hash disappear, not both of them.
BTW, if (let me say it again) there is no client-side routing involved, you could get away with using .path()
for setting the hash without the need to turn on html5 mode (but it's more of a hack, than a real solution).
@petebacondarwin: It would have made sense for !
to be the default hashPrefix
from the beginning. At this point I am not sure the benefits warrant the BC. Could go either way, but I slighlty lean towards leaving it as is.
All our routes now have !# which has broken some links. I take it this is a breaking change?
Yes, I've literally just stumbled on this too.
It breaks the Yeoman generated project that I just created, which had all the same settings as one made only fairly recently (but presumably that will have been before the BC went out)
You're probably all much better devs than me :smile: , but for anyone else who stumbles on this and simply wants to undo the BC, it's just a matter of putting this in the .config:
```javascript
.config(function ($routeProvider, $locationProvider) {
...
// undo the default ('!')
$locationProvider.hashPrefix('');
});
Yes this is a breaking change. See
https://docs.angularjs.org/guide/migration#migrating-from-1-5-to-1-6
and
https://github.com/angular/angular.js/blob/master/CHANGELOG.md#location-due-to
and
https://github.com/angular/angular.js/commit/aa077e81129c740041438688dff2e8d20c3d7b52
Most helpful comment
Yes, I've literally just stumbled on this too.
It breaks the Yeoman generated project that I just created, which had all the same settings as one made only fairly recently (but presumably that will have been before the BC went out)
You're probably all much better devs than me :smile: , but for anyone else who stumbles on this and simply wants to undo the BC, it's just a matter of putting this in the .config:
```javascript
.config(function ($routeProvider, $locationProvider) {
...
// undo the default ('!')
$locationProvider.hashPrefix('');
});