Tobbe Tobbe - 2 months ago 24
AngularJS Question

"10 $digest() iterations reached. Aborting!" with angular.copy and ng-repeat

Why do I get in to a digetst loop when I repeat over a cloned array?



angular.module('myApp', [])
.controller('Ctrl1', function(MyService) {
var $ctrl = this;

$ctrl.getData = MyService.getData;
})
.service('MyService', function () {
var data = [
{
name: 'Adam',
age: 12
}, {
name: 'Bob',
age: 14
}, {
name: 'Caesar',
age: 15
}];

this.getData = function () {
// This is the offending line. If I remove the call to
// angular.copy it works but in my real scenario I want to
// modify the copy of `data` before returning it, without
// affecting the original version. That's why I need to clone
// it first.
return angular.copy(data);
};
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js"></script>
<div ng-app="myApp" ng-controller="Ctrl1 as $ctrl">
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
<tr ng-repeat="data in $ctrl.getData()">
<td>{{data.name}}</td>
<td>{{data.age}}</td>
</tr>
</table>
</div>




Answer

You used $ctrl.getData()(binding) on view which does return an data array copy using angular.copy. So what happens is when digest cycle start it evaluates$ctrl.getData()and returnsdatacopy, dues to reference change inwatcher(binding) value. Angular re-runs digest cycle(it happens till all the binding gets stable). Again it tries to evaluate$ctrl.getData()value get and new copy ofdata` array. So this process goes on as every time you are changing the reference of binding variable. Since after reaching to 10th operation it throws an error (by default angular digest cycle TTL = 10).

How digest cycle?

  1. It goes through page collects all the bindings & put those expressions inside $$watchers array of $scope.
  2. It starts initial digest cycle to evaluate of bindings, & update corresponding model value on page.
  3. Digest cycle internally performs dirty checking, where it loop through all the $$watchers array & evaluate there bindings against $scope. Dirty checking meaning it check watcher expression currently evaluated value with its old value.
  4. If any changes are found in dirty checking then again it re-run digest cycle from top to bottom(from $rootScope to all childs).
  5. Until all the bindings gets stable this process happens.

To fix this error you have to maintain two copies of variable in your code.

Comments