You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
$location runs into infinite digest under certain circumstances #1417
when adding Angular to an existing project that makes use of html5 history. Whenever the url is changed outside of Angular, the next $digest to run produces this error:
I have my own routing in place, using goog.history.Html5History. I was trying to include some Angular stuff on a single page (works), but when the page changes, the first subsequent $apply produces the above error. It looks like the $location service is getting out of sync with the browser.
$locationWatch expects the $location service to be updated first, followed by the browser. But when I pushState to the browser directly, the $location service still has the old url.
The sad thing is that $location is not being used directly by this app, nor is $route. It's ngInclude, that depends on $anchorScroll, which depends on $location - maybe fixing this dependency should be a separate issue... (to be investigated)
I also ran into this bug recently. For me it happened while testing in IE8 with html5Mode(true) (which in IE8 falls back to html5Mode(false), of course).
This is also happening to me in Chrome (Version 22.0.1229.94 m), when using window.history.pushState in response to a button click. Angular version: 1.0.2.
For what it's worth, I was having this issue in IE9 and Android and here is what I did:
Make sure you have a route to '/' in Angular and that it works properly - for example: $routeProvider.when('/', {templateUrl: 'partials/home', controller: HomeCtrl});
Add $locationProvider.html5Mode(true).hashPrefix('!'); to your app configuration
I had to add the following code to get android to work and I just added it in a script tag before angular loads etc.
var buggyAndroid = parseInt((/android (\d+)/.exec(window.navigator.userAgent.toLowerCase()) || [])[1], 10) < 4;
var buggyAndroid = parseInt((/android (\d+)/.exec(window.navigator.userAgent.toLowerCase()) || [])[1], 10) < 4;
if (!history.pushState || buggyAndroid) {
if (window.location.hash) {
if(window.location.pathname !== '/') window.location.replace('/#!' + window.location.hash.substr(2)); //Hash and a path, just keep the hash (redirect)
} else {
if (window.location.pathname === '/') window.location.replace('/#!/'); //No hash, no path
else window.location.replace('/#!' + window.location.pathname); //No hash, but have a path, take path
}
}
Here is an example where the initial page load fails and reloads after throwing the above error. http://jsfiddle.net/v7HG5/ (Open in IE)
Note: jsfiddle doesn't handle any angular routing, so the rendered view is a blank jsfiddle. Also, nothing will happen at all on an html5 supported browser.
My understanding is that the page is going to need to refresh to convert the url from html5 mode to hash mode (adding the "#" http://jsfiddle.net/#/v7HG5/). In my case this is fine, but it should handle its errors.
Also problem with html5Mode(true) and IE8. Everything works in Chrome/FF, but in IE Angular is unable to bootstrap because the $locationWatcher keeps getting a new value, and thus $digest fails. This results in a redirection loop (for reasons not totally clear to me) where IE keeps redirecting to the "index" page and Angular fails to bootstrap.
Any news on this issue?
Right now the team is contemplating setting html5Mode(false) and rewriting the routing on the server side.
I've managed to reduce the occurance of this bug significantly by using $location.path() and $location.search() instead of manually using location.href. Hope that helps someone else.
@gaiottino were you using angular for routing or an external plugin? because i would love to see the solution for app that uses an external plugin but want to watch the url change
@leonzinger I was iterating an app which relied on crossroads.js and Handlebars to Angular. It worked great for Chrome/FF/Safari, but IE would have $digest problems described above. I've removed crossroads.js now in favor of using Angular for routing but with a patch I'm hoping will make it's way into master: #1901
What fixed the infinite redirecting issue for us was removing the "otherwise" block, from our routeProvider. We have a unique situation of 2 angularJS applications running in the same page, so this fix might not be the fix for everyone.
This problem appeared with migration to 1.3 and was related to injecting $location into a service. It was happily working before the change. Used the suggestion by @swlasse (cheers) to get around the problem.
dca2317, which closed that issue, does not fix the problem raised by @IgorMinar in this issue's initial description. @IgorMinar, the issue you described in #1417 (using "Angular in an existing project that makes use of html5 history (goog.history.Html5History for example) is not IE-specific at all.
This is a major issue. This makes Angular in my way, even when I don't use the $location service.
The only workaround I've found involves monkey-patching the $location provider's $get function. By changing the $get function we prevent the provider from installing the problematic watches. See camptocamp/ngeo#160. I'd really like to fix Angular instead, but, at this point, I don't know what a proper fix would look like.
Hmm, I did simple think and it seems me to that it really helped. I do some redirection after a user logged in and simply wrapping my redirect call into setTimeout method help with the $location event loop.
Activity
dbinit commentedon Sep 25, 2012
Here is a jsFiddle that reproduces the issue: http://jsfiddle.net/dbinit/tMmKf/
martinstein commentedon Oct 29, 2012
I also ran into this bug recently. For me it happened while testing in IE8 with
html5Mode(true)(which in IE8 falls back to html5Mode(false), of course).kstep commentedon Nov 2, 2012
I confirm this bug for AngularJS 1.1.0 and IE9.
fr0 commentedon Nov 8, 2012
This is also happening to me in Chrome (Version 22.0.1229.94 m), when using window.history.pushState in response to a button click. Angular version: 1.0.2.
gaiottino commentedon Nov 14, 2012
Any update to this? Giving us some IE9 headaches.
scottweinert commentedon Nov 23, 2012
I am also experiencing this in IE9. Any update?
ThomasDeutsch commentedon Nov 26, 2012
having the same problem. Still no fix for this?
scottweinert commentedon Nov 26, 2012
For what it's worth, I was having this issue in IE9 and Android and here is what I did:
Make sure you have a route to '/' in Angular and that it works properly - for example: $routeProvider.when('/', {templateUrl: 'partials/home', controller: HomeCtrl});
Add $locationProvider.html5Mode(true).hashPrefix('!'); to your app configuration
I had to add the following code to get android to work and I just added it in a script tag before angular loads etc.
var buggyAndroid = parseInt((/android (\d+)/.exec(window.navigator.userAgent.toLowerCase()) || [])[1], 10) < 4;
var buggyAndroid = parseInt((/android (\d+)/.exec(window.navigator.userAgent.toLowerCase()) || [])[1], 10) < 4;
if (!history.pushState || buggyAndroid) {
if (window.location.hash) {
if(window.location.pathname !== '/') window.location.replace('/#!' + window.location.hash.substr(2)); //Hash and a path, just keep the hash (redirect)
} else {
if (window.location.pathname === '/') window.location.replace('/#!/'); //No hash, no path
else window.location.replace('/#!' + window.location.pathname); //No hash, but have a path, take path
}
}
dbinit commentedon Nov 26, 2012
In my case, I wasn't using $location at all. It was just getting pulled in by $anchorScroll, which is used by ngInclude.
I wasn't using $anchorScroll either, so I just did this to remove the dependency:
If you're using $anchorScroll you could probably just null out $location instead.
pgte commentedon Dec 12, 2012
I'm running into this and I don't have explicit watchers and I don't import $location.
When I do history.pushState(...) I get the following error:
Any ideas?
brandonsalmon commentedon Jan 3, 2013
Here is an example where the initial page load fails and reloads after throwing the above error.
http://jsfiddle.net/v7HG5/ (Open in IE)
Note: jsfiddle doesn't handle any angular routing, so the rendered view is a blank jsfiddle. Also, nothing will happen at all on an html5 supported browser.
My understanding is that the page is going to need to refresh to convert the url from html5 mode to hash mode (adding the "#" http://jsfiddle.net/#/v7HG5/). In my case this is fine, but it should handle its errors.
ThomasBorghs commentedon Feb 7, 2013
Also problem with
html5Mode(true)and IE8. Everything works in Chrome/FF, but in IE Angular is unable to bootstrap because the $locationWatcher keeps getting a new value, and thus $digest fails. This results in a redirection loop (for reasons not totally clear to me) where IE keeps redirecting to the "index" page and Angular fails to bootstrap.Any news on this issue?
Right now the team is contemplating setting
html5Mode(false)and rewriting the routing on the server side.gaiottino commentedon Feb 7, 2013
I've managed to reduce the occurance of this bug significantly by using $location.path() and $location.search() instead of manually using location.href. Hope that helps someone else.
leonzinger commentedon Feb 10, 2013
@gaiottino were you using angular for routing or an external plugin? because i would love to see the solution for app that uses an external plugin but want to watch the url change
gaiottino commentedon Feb 11, 2013
@leonzinger I was iterating an app which relied on crossroads.js and Handlebars to Angular. It worked great for Chrome/FF/Safari, but IE would have $digest problems described above. I've removed crossroads.js now in favor of using Angular for routing but with a patch I'm hoping will make it's way into master: #1901
63 remaining items
toblender commentedon Oct 15, 2014
What fixed the infinite redirecting issue for us was removing the "otherwise" block, from our routeProvider. We have a unique situation of 2 angularJS applications running in the same page, so this fix might not be the fix for everyone.
camden-kid commentedon Nov 4, 2014
This problem appeared with migration to 1.3 and was related to injecting $location into a service. It was happily working before the change. Used the suggestion by @swlasse (cheers) to get around the problem.
elemoine commentedon Feb 4, 2015
dca2317, which closed that issue, does not fix the problem raised by @IgorMinar in this issue's initial description. @IgorMinar, the issue you described in #1417 (using "Angular in an existing project that makes use of html5 history (goog.history.Html5History for example) is not IE-specific at all.
This is a major issue. This makes Angular in my way, even when I don't use the
$locationservice.elemoine commentedon Feb 5, 2015
The only workaround I've found involves monkey-patching the
$locationprovider's$getfunction. By changing the$getfunction we prevent the provider from installing the problematic watches. See camptocamp/ngeo#160. I'd really like to fix Angular instead, but, at this point, I don't know what a proper fix would look like.Fixat "infinit loop" problem i IE11 med hjälp härifrån: angular/angul…
smirnovigor commentedon Mar 23, 2015
In my app I don't use
$locationand I patch this issue with this decoration:azachar commentedon May 5, 2015
Thank you, @smirnovigor ! Well, it works and it doesn't work too. With UI-Router it doesn't replace the url with a new state's url...
azachar commentedon May 5, 2015
Hmm, I did simple think and it seems me to that it really helped. I do some redirection after a user logged in and simply wrapping my redirect call into setTimeout method help with the $location event loop.
setTimeout(function({
$location.path('....')
},500);
Not elegant, but it works!
caviles commentedon May 13, 2015
You guys are so awesome changing window.replace to $location.path(url_step2_view); worked amazingly. THANKSSSSSSS!!!!!!!!!!
STATISTIK-1211 Fixat en oändlig loop som kunde uppstå i IE11 om man f…
M0ns1gn0r commentedon Sep 4, 2015
Thanks @azachar! Your timeout workaround helped in my case.
creativegeekjp commentedon Sep 19, 2015
@azachar's timeout workaround worked for me too.
comfroels commentedon Sep 22, 2015
@smirnovigor You are the MAN! Been working on this for 2 days! The decorator works everyone!
leye0 commentedon Nov 10, 2015
@caviles You didn't solve a bug, you weren't using $location. This bug is about $location.
natee commentedon May 3, 2016
In my case, I used window.location.href = 'xxx', when I changed it to $location.path(), It worked fine.