setting location with trailing hash causes $digest() iterations reached exception #8980
Description
in angular 1.2.23
to get the browser to scroll to an anchor tag (using the $anchorScroll service), we set $location.hash('foo'). When an event triggers (like a mouseclick), the digest exceptions reached triggers with a message like
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 152; oldVal: 151"],["fn: $locationWatch; newVal: 153; oldVal: 152"],["fn: $locationWatch; newVal: 154; oldVal: 153"],["fn: $locationWatch; newVal: 155; oldVal: 154"],["fn: $locationWatch; newVal: 156; oldVal: 155"]]
http://errors.angularjs.org/1.2.23/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3…n%3A%20%24locationWatch%3B%20newVal%3A%20156%3B%20oldVal%3A%20155%22%5D%5D
The root cause is the location Watch looking at oldUrl != $location.absUrl() to determine a change but absUrl returns the URL without the trailing hash, i.e.
oldUrl = $browser.url() = http://host.com/Dashboard#!/#foo"
$location.absUrl() = "http://host.com/Dashboard#!/"
var changeCounter = 0;
$rootScope.$watch(function $locationWatch() {
var oldUrl = $browser.url();
var currentReplace = $location.$$replace;
if (!changeCounter || oldUrl != $location.absUrl()) {
changeCounter++;
$rootScope.$evalAsync(function() {
if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
defaultPrevented) {
$location.$$parse(oldUrl);
} else {
$browser.url($location.absUrl(), currentReplace);
afterLocationChange(oldUrl);
}
});
}
$location.$$replace = false;
return changeCounter;
});