Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - Error: 10 $digest() iterations reached. Aborting

i'm trying to put a random integer in my ng-src path, like that:

<div ng-repeat="user in users">
      <img ng-src="{{randomPicture()}}" alt="">
</div>

And here's my basic function in my controller:

$scope.randomPicture = function(){
  var PATH = 'assets/images/';
  var image = Math.floor((Math.random() * 12) + 1);
  var ext = '.jpg';
  var randomPic = PATH + image + ext;

  return randomPic;
};

The images are displayed but in the console i have this error:

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

I found many questions on that here in stackoverflow but i still can't get rid of that error. Thanks for your help.

like image 226
adam Avatar asked Mar 26 '15 11:03

adam


1 Answers

Your binding being random, it will be different every time Angular will execute the watcher of this binding.

However, Angular only stops a digest cycle when it reaches a stable state where all the watchers return the same value twice in a row, which never happens with yours.

In short, you cannot bind a random value, or anything that is always different, in an Angular binding. You should generate your picture once, and optionally re-randomize it based on some event.

$scope.randomPicture = generateRandomPicture();

And

<img ng-src="{{randomPicture}}">

UPDATE: And if you want to refresh the picture every 3 seconds for instance, you could add

// Generate a new random picture every 3 seconds
$interval(function() {
  $scope.randomPicture = generateRandomPicture();
}, 3000);

Update 2: Now that I understand better your problem, I would either suggest to keep everything as is but use :: as shown below if using Angular 1.3 at least. This way you will have one random picture generated per user, but generated only once.

On an earlier verison of Angular or alternatively, you could generate a determinist image per user that would feel random. for instance in your HTML use:

<img ng-src="{{randomPicture($index)}}">

And in your controller

var rand1 = Math.round(Math.random()*10);
var rand2 = Math.round(Math.random()*10);

$scope.randomPicture = function(index) {
  var PATH = 'assets/images/';
  var image = (index+rand1*rand2)%13 + 1;
  var ext = '.jpg';
  var randomPic = PATH + image + ext;

  return randomPic;
};


Note that if you're using Angular 1.3+ and only want to generate the picture once, you can use ont-time binding using the :: syntax (using the same code for randomPicture):
<img ng-src="{{::randomPicture()}}">
like image 101
floribon Avatar answered Oct 19 '22 04:10

floribon