1

Why does the following give the error:

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

Code

<div ng-app>
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
      <span ng-bind="getText()"></span>
  </div>
</div>

function TodoCtrl($scope) {
  $scope.todos = [
    {text:'learn angular', done:true},
    {text:'build an angular app', done:false}];

    $scope.getText = function() {
        var names = $scope.todos.map(function(t) { 
            return t.text;
        });
        return names;
    }
  };

The code block is supposed to grab all todos and then render their names in a list using ng-bind. It works, but tons of digest iteration errors show up in console.

jsfiddle

2 Answers 2

1

It is really a bad practice to use a function evaluation in ng-bind, reason for this infinite digest cycle is because your digest cycle never gets settled. Everytime digest cycle happens ng-bind expression also runs and since the return value from ng-bind expression is always different (different object reference produced by array.map) it has to rerun the digest cycle again and it goes on until reached the max limit set, i.e 10.

In your specific case you could just set the names as a scope property and ng-bind="name".

   $scope.names = $scope.todos.map(function(t) { 
        return t.text;
    }).join();

As a general rule you can make sure you update the property name only when needed from your controller, example when an event occurs like adding a todo, removing a todo etc.. A typical scenario in this answer. You could also use interpolation instead of ng-bind and use function expression. {{}}. ie:

 $scope.getText = function() {
        return $scope.todos.map(function(t) { 
            return t.text;
        }).join();

    }

and

<span>{{getText()}}</span> <!--or even <span ng-bind="getText()"></span>-->

Fiddle

Sign up to request clarification or add additional context in comments.

4 Comments

That seems best when the controller deals with small amounts of data. Is that best practice in larger applications that may have 20+ other scope variables similar to todos? That would mean creating 2x the number of scope variables just to hold a subset of the already existing information. I thought calling a function that filters if for you would be easier?
@fanhats There is something called viewmodel which is specifically for this purpose. But the idea is that you understand what is the issue that is causing this and what are the possible scenarions as i have covered in my answer. it is upto you to chose what you need. But i really thought it is better to explain what is going on and also if you always evaluate a function expression in ng-bind/interpolate you need to remember it runs during every digest cycle and if you are doing an expensive stuff there it could just slow down your entire application.
20+ other scope variables similar to todos it really depends on how you design. You cannot just blindly say create a separate scope property for everything. There are numerous ways to display a data so it is upto you to chose what you need keeping in mind the digest cycle/ watches and performance.
@fanhats Also please see this answer similar issue as yours.
1

I feel like you have over complicated this i have updated the fiddle with a working solution http://jsfiddle.net/U3pVM/12417/.

<div ng-app>
  <h2>Todo</h2>
  <div ng-controller="TodoCtrl">
      <div ng-repeat="todo in todos"> 
          <span >{{ todo.text}}</span>
      </div>

  </div>
</div>

function TodoCtrl($scope) {
  $scope.todos = [
    {text:'learn angular', done:true},
    {text:'build an angular app', done:false}];

  };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.