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.