On Chrome for iOS, the part of the URL that should be returned by $location.hash() is sometimes append to the result of $location.path(). In cases where the path and the hash are returned correctly, reloading the page a couple times will reproduce the issue.
It seems to have something to do with how Chrome for iOS encodes the second # in the URL. So it's possible that its not something that can be fixed here.
In the demo I created, I tried another 3rd party iOS browser called Mercury and found that it did not have this issue. So it doesn't seem to be something that can't be fixed because of UIWebView.
I'm also seeing this in my project. Calling $location.hash() is causing Chrome on iOS to hang/crash for our application.
Guys, testing this ("Mozilla/5.0 (iPad; CPU OS 7_1_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D201 Safari/9537.53", snapshot, http://plnkr.co/edit/6GBmSLfvOtskeXcNmigp?p=preview) I can't seem to reproduce the issue.
Are you still having this issue with the latest code? (I don't have any older iOS devices to test with unfortunately, so this may affect safari 6 or older ._.)
@caitp, it looks like you are using Safari? This is a Chrome for iOS bug. Safari is not affected.
Oh, you're right, I misread.
Looking into it againnnnn
hmmm, well I do see that we are encoding the second hash in the URL, however I have tried for a few minutes and can't reproduce the issue described by the original poster.
Google Chrome 36.0.1985.49 (Official Build bb388542b4eceba575bd68a615aa07ee1691e3e3), Mozilla/5.0 (iPad; CPU OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) CriOS/36.0.1985.49 Mobile/11D257 Safari/9537.53
If this is still occurring, specific repro steps would be useful, because "sometimes this happens" is very difficult to act on
Sure, let me try screenshots:
Go to http://bschoenfeld.github.io/angular-location-hash-bug/#/foo#bar in Chrome on iOS.
Notice that path is /foo and hash is bar.

Focus the URL and click Go to reload the page.
The path is /foo and hash is bar as before, so that's good. The URL is now encoded differently, but it hasn't caused any issues yet.

Focus the URL and click Go to reload the page one more time.
The path is now `/foo#bar' and the hash is empty. That is the bug.

I'm seeing this bug as well. I have one solution with a decorator and one with a patch to angular, we're using an old version of angular so I'm not going to try and submit a PR with this but here it is for reference.
function parseAppUrl(relativeUrl, locationObj, appBase) {
var prefixed = (relativeUrl.charAt(0) !== '/');
if (prefixed) {
relativeUrl = '/' + relativeUrl;
}
var match = urlResolve(relativeUrl, appBase);
//BEGIN PATCH
var pathSplit = match.pathname.split('%23');
if (pathSplit.length > 1) {
match.pathname = pathSplit[0];
match.hash = pathSplit[1];
}
//END PATCH
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
match.pathname.substring(1) : match.pathname);
locationObj.$$search = parseKeyValue(match.search);
locationObj.$$hash = decodeURIComponent(match.hash);
// make sure path starts with '/';
if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') {
locationObj.$$path = '/' + locationObj.$$path;
}
}
Here's the decorator solution.
app.config(['$provide', function($provide) {
$provide.decorator('$browser', ['$delegate', function($delegate) {
var originalUrl = $delegate.url;
$delegate.url = function() {
var result = originalUrl.apply(this, arguments);
if (result && result.replace) {
result = result.replace(/%23/g, '#');
}
return result;
};
return $delegate;
}]);
}]);
EDIT: minification safe
Excellent, @gabe-untapt. Thanks for the help.
@caitp, have you had a chance to try and reproduce this using my guide with screenshots above?
In terms of the bigger picture, I was just looking at this test: https://github.com/angular/angular.js/blob/e0adb9c452e172295209f785b62472688225fffb/test/ng/locationSpec.js#L298-L307
It seems like angular says that a %23 in the url should not ever be interpreted as a hash separator but should be decoded by the browser into a # character in either the path or hash attribute. Looks like this is where the browser incompatibility is happening as mobile chrome is encoding the # character automatically.
@gabe-untapt you are my hero! Thanks so much for posting your solution. My app is using an older version as well and your decorator wound up being a perfect solution for us.
Experiencing this issue as well. @gabe-untapt 's solution works great on angular 1.2.21.
This is an issue for our app too. @gabe-untapt fix worked in Angular 1.3.6, many thanks!
@gabe-untapt You saved my time alot. Great decorator.
Great work, you helped me a lot :) :+1:
@gabe-untapt Thanks for saving me a lot of time :+1:
Great work @gabe-untapt fix worked in Angular 1.5.7, many thanks!
Most helpful comment
I'm seeing this bug as well. I have one solution with a decorator and one with a patch to angular, we're using an old version of angular so I'm not going to try and submit a PR with this but here it is for reference.
Here's the decorator solution.
EDIT: minification safe