Angular troubleshooting "10 $ digest () iterations achieved" Error

10 $ digest () iterations. Aborting!

There is a lot of supporting text in the sense of “Observers fired in the last 5 iterations”, etc., but many of this text is Javascript code from various functions. Are there rules for diagnosing this problem? Is this a problem that can ALWAYS be mitigated or are there applications complex enough to be considered as just a warning?

+82
angularjs
Jun 14 '13 at 19:43
source share
13 answers

as Ven said, you either return different (not identical) objects in each $digest cycle, or you modify the data too often.

The quickest solution to find out which part of your application is causing this behavior:

  • remove all suspicious HTML - basically remove all your html from the template and check for warnings
  • if there are no warnings, add small parts of the html you are removing and check if the problem is correct.
  • repeat step 2 until you get a warning - you will understand how much of your html is responsible for the problem.
  • We investigate further - the part from step 3 is responsible for either mutating objects in $scope or returning non-identical objects in each $digest cycle.
  • if after step 1 you still have warnings of the $digest iteration, than you are probably doing something very suspicious. Repeat the same steps for the parent template / area / controller.

You also want to make sure that you do not change the input of custom filters.

Keep in mind that in JavaScript there are certain types of objects that do not behave as you would normally expect:

 new Boolean(true) === new Boolean(true) // false new Date(0) == new Date(0) // false new String('a') == new String('a') // false new Number(1) == new Number(1) // false [] == [] // false new Array == new Array // false ({})==({}) // false 
+72
Jun 16 '13 at 0:55
source share

This usually happens when you return a different object each time.

For example, if you use this in ng-repeat :

 $scope.getObj = function () { return [{a: 1}, {b: 2}]; }; 

You will get this error message because Angular is trying to get "stability" and will execute the function until it returns the same result 2 times (compared to === ), which in our case will never return true because the function always returns a new object.

 console.log({} === {}); // false. Those are two different objects! 

In this case, you can fix this by directly saving the object in the area, for example.

 $scope.objData = [{a: 1}, {b: 2}]; $scope.getObj = function () { return $scope.objData; }; 

This way you always return the same object!

 console.log($scope.objData === $scope.objData); // true (a bit obvious...) 

(You should never run into this, even in complex applications).

Update: Angular has added a more detailed explanation on its website .

+70
Jun 14 '13 at 19:56
source share

Just wanted to drop this solution here, hope it helps others. I was getting this iterative problem because I was iterating over the generated property, which created a new object every time it was called.

I fixed it by caching the generated object on the first request, and then always returning the cache if it existed. A dirty () method has also been added, which will destroy caching results as needed.

I had something like this:

 function MyObj() { var myObj = this; Object.defineProperty(myObj, "computedProperty" { get: function () { var retObj = {}; return retObj; } }); } 

And here with the implemented solution:

 function MyObj() { var myObj = this, _cached; Object.defineProperty(myObj, "computedProperty" { get: function () { if ( !_cached ) { _cached = {}; } return _cached; } }); myObj.dirty = function () { _cached = null; } } 
+11
Jul 26 '14 at 5:22
source share

I had the same problem: every time I created a new date. Therefore, for those dealing with dates, I converted all calls like this:

 var date = new Date(); // typeof returns object 

at

 var date = new Date().getTime(); // typeof returns number 

Initializing the number instead of the date object solved it for me.

+6
Jan 30 '15 at 22:23
source share

There is also the possibility that it is not an infinite loop. 10 iterations is not a large enough number to conclude that with any certainty. Therefore, before setting off in pursuit of wild geese, it may be advisable to first exclude this possibility.

The easiest way to do this is to increase the maximum number of digest cycles to a much larger number, which can be done in the module.config method using the $rootScopeProvider.digestTtl(limit) method. If the infdig error no longer appears, you simply have a fairly sophisticated update logic.

If you are creating data or views based on a recursive clock, you can look for iterative solutions (i.e. do not rely on new digest cycles to be run) using while , for or Array.forEach . Sometimes a structure is simply heavily nested and not even recursive, there is probably not much to be done in those cases, with the exception of raising the limit.

Another method of debugging errors is to view digest data. If you print JSON, you get an array of arrays. Each top-level entry is an iteration; each iteration consists of a list of clock entries.

If, for example, you have a property that is modified in $watch on yourself, it is easy to see that the value changes endlessly:

 $scope.vm.value1 = true; $scope.$watch("vm.value1", function(newValue) { $scope.vm.value1 = !newValue; }); 
 [ [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ] ] 

Of course, in a larger project, this may not be so simple, especially since the msg field often has the value "fn: regularInterceptedExpression" if the clock is an interpolation {{ }} .

In addition to this, of course, the methods already mentioned are useful, such as shortening the HTML code to find the source of the problem.

+4
Aug 16 '16 at 17:53 on
source share

This is a known bug in ui-router , it helped us: https://github.com/angular-ui/ui-router/issues/600

+1
Sep 11 '15 at 15:04
source share

simple way: use angular.js and not the min file. open it and find the line:

 if ((dirty || asyncQueue.length) && !(ttl--)) { 

add line below:

 console.log("aaaa",watch) 

and then refresh your page, in the development tools console you will find the error code.

+1
Feb 18 '17 at 13:03 on
source share

I would also like to mention that I received this error message when I had a typo in the templateUrl custom directive that I had in my project. Due to typos, the template could not be loaded.

 /* @ngInject */ function topNav() { var directive = { bindToController: true, controller: TopNavController, controllerAs: 'vm', restrict: 'EA', scope: { 'navline': '=', 'sign': '=' }, templateUrl: 'app/shared/layout/top-navTHIS-IS-A-TYPO.html' }; 

Look at the Network tab of your web browser tools and see if any resource has a 404 error.

It is easy to overlook, because the error message is very mysterious and, apparently, is not related to the real problem.

0
Jul 31 '16 at 4:47
source share

I had this problem in my project because in .otherwise () my route definition was missing and I ended up in the wrong route.

0
Aug 10 '16 at 17:50
source share

I had this problem because I was doing it

 var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id = rawMaterial.id; }); 

Instead: (notice = vs ===), my unit test started to break, and I found my dumbness

 var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id === rawMaterial.id; }); 
0
Feb 12 '17 at 1:32
source share

I ran into this problem when I needed a dynamic tooltip ... it made angular recount it every time as a new value (although it was the same). I created a function to cache the calculated value as follows:

 $ctrl.myObj = { Title: 'my title', A: 'first part of dynamic toolip', B: 'second part of dynamic tooltip', C: 'some other value', getTooltip: function () { // cache the tooltip var obj = this; var tooltip = '<strong>A: </strong>' + obj.A + '<br><strong>B: </strong>' + obj.B; var $tooltip = { raw: tooltip, trusted: $sce.trustAsHtml(tooltip) }; if (!obj.$tooltip) obj.$tooltip = $tooltip; else if (obj.$tooltip.raw !== tooltip) obj.$tooltip = $tooltip; return obj.$tooltip; } }; 

Then in html I turned to it like this:

 <input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted"> 
0
Mar 23 '17 at 21:55
source share

this is how I approached him and found a solution: I checked the text, he showed:

 Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! 

Observers have worked for the last 5 iterations: [[{"" msg ":" operator === statment && functionCall () "," newVal ": [{" id ": 7287," referen ...

so if you can see

tzd

that the charter generates an error. I checked the function called in this post, I returned (false) from all of them, just to determine which one has the problem. one of them called a function that constantly changes the return result, which is a problem.

0
Jan 18 '19 at 14:10
source share

As crazy as it sounds, I fixed this error by simply restarting my browser when it just appeared suddenly.

So, one solution is to simply clear the browser cache or try restarting the browser.

-2
Oct 12 '17 at 11:14
source share



All Articles