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

setting location with trailing hash causes $digest() iterations reached exception #8980

Closed
patrickdyson opened this issue Sep 8, 2014 · 3 comments

Comments

@patrickdyson
Copy link

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;
});
@btford
Copy link
Contributor

btford commented Sep 8, 2014

Can you please provide a reproduction via jsbin, plnkr.co or jsfiddle. This saves us a lot of time. Thanks!

@patrickdyson
Copy link
Author

We have not been able to reproduce it on plnkr yet. By going back to 1.2.21 with our app, the problems go away. We have seen several instances and it was a bit confusing, but they all have the same core issue that the code in $browser.url has a cached version of the current url (lastBrowserUrl), but location.href is different.

So $location.absUrl gets set to /bar, locationWatch fires, it checks browser.url which returns location.href (which is /foo), sees that it is different, calls browser.url(/bar). That checks lastBrowserUrl, but that is already /bar, so it does nothing. That then iterates until the iteration limit is reached.

We will try to create a simple reproducible case but I'm not hopeful. I can give access to a dev server that does make the issue happen reliably, lmk if that is interesting.

hmm, this has very similar symptoms #6976

@patrickdyson
Copy link
Author

1.2.24 fixes our issue, appears that the bug fix for #6976 gets our issue also. I will close this as a dup of that one

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

No branches or pull requests

2 participants