I have the following code which repeats and displays name of the user and his score:
<div ng-controller="AngularCtrl" ng-app>
<div ng-repeat="user in users | orderBy:predicate:reverse | limitTo:10">
<div ng-init="user.score=user.id+1">
{{user.name}} and {{user.score}}
</div>
</div>
</div>
And the corresponding angular controller.
function AngularCtrl($scope) {
$scope.predicate = 'score';
$scope.reverse = true;
$scope.users = [{id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}, {id: 11, name: 'John'}, {id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}]
}
When I run the above code, I get the Error: 10 $digest() iterations reached. Aborting! error in my console.
I have created jsfiddle for same.
http://jsfiddle.net/JSWorld/7ecYd/1/
The sort predicate is being initalized only inside the ng-repeat and also the limit is being applied on the number of objects. so I feel having both the sortby and limitTo watchers together is the reason for error.
If the $scope.reverse is false (ascending order of score), then it does not error.
Can anyone help me understand what is wrong here? Much appreciate your help.
Please check this jsFiddle: http://jsfiddle.net/bmleite/Hp4W7/. (The code is basically the same you posted but I use an element instead of the window to bind the scroll events).
As far as I can see, there is no problem with the code you posted. The error you mentioned normally occurs when you create a loop of changes over a property. For example, like when you watch for changes on a certain property and then change the value of that property on the listener:
$scope.$watch('users', function(value) {
$scope.users = [];
});
This will result on an error message:
Uncaught Error: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: ...
Make sure that your code doesn't have this kind of situations.
update:
This is your problem:
<div ng-init="user.score=user.id+1">
You shouldn't change objects/models during the render or otherwise it will force a new render (and consequently a loop, which causes the 'Error: 10 $digest() iterations reached. Aborting!').
If you wan to update the model, do it on the Controller or on a Directive, never on the view. angularjs documentation recommends not to use the ng-init exactly to avoid these kind of situations:
Use ngInit directive in templates (for toy/example apps only, not recommended for real applications)
Here's a jsFiddle with an working example: http://jsfiddle.net/bmleite/7ecYd/3/
The cause of this error for me was...
ng-if="{{myTrustSrc(chat.src)}}"
in my template
It causes the function myTrustSrc in my controller to be called in an endless loop. If I remove the ng-if from this line, then the problem is solved.
<iframe ng-if="chat.src" id='chat' name='chat' class='chat' ng-src="{{myTrustSrc(chat.src)}}"></iframe>
The function is only called a few times when ng-if isn't used. I still wonder why the function is called more than once with ng-src?
This is the function in the controller
$scope.myTrustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
It's weird ... I've got the exact same error, coming from a different thing. When I create my controller I passed the $location parameter, like this :
App.controller('MessageController', function ($scope, $http, $log, $location, $attrs, MessageFactory, SocialMessageFactory) {
// controller code
});
This was proven to be a bug https://github.com/angular/angular.js/issues/1417 when we use third party libraries or pure JS to manipulate some specifics (here window.location) the next digest of angular will blow this error.
So I simply removed the $location from the controller creation parameter, and it worked again, without this error.
Or if you absolutly need to use the $location from angular, you have to remove every single <a href="#">link</a> in the links of your template page, and rather write href="". Worked for me.
Hope it can help one day.
I have another example of something that caused this. Hopefully it helps for future reference. I'm using AngularJS 1.4.1.
I had this markup with multiple calls to a custom directive:
<div ng-controller="SomeController">
<myDirective data="myData.Where('IsOpen',true)"></myDirective>
<myDirective data="myData.Where('IsOpen',false)"></myDirective>
</div>
myData is an array and Where() is an extension method that iterates over the array returning a new array containing any items from the original where the IsOpen property matches the bool value in the second parameter.
In the controller I set $scope.data like this:
DataService.getData().then(function(results){
$scope.data = results;
});
Calling the Where() extension method from the directive like in the above markup was the problem. To fix this issue I moved the call to the extension method into the controller instead of the markup:
<div ng-controller="SomeController">
<myDirective data="openData"></myDirective>
<myDirective data="closedData"></myDirective>
</div>
and the new controller code:
DataService.getData().then(function(results){
$scope.openData = results.Where('IsOpen',true);
$scope.closedData = results.Where('IsOpen',false);
});