3

The problem occurs when trying to ng-repeat over dynamically created collection: Angular is going in to loop with 10 $digest() iterations reached. Aborting! error

I have simplified the problem to minimum with this example

<body ng-init='a = [1, 2, 3]'>
    <div ng-repeat="item in a.reverse()">{{item}}</div>
</body>

and here is it working copy in Plunkr (View shows correct result, but in console you will see errors mentioned above. More complicated examples fail completely)

Considered [1, 2, 3] could be array of objects, if it may make any difference

So questions are why is it so, and is there an easy way to come over this?

Thanks

2
  • 1
    take a look at this link stackoverflow.com/questions/15266671/… Commented Dec 31, 2014 at 13:13
  • Current example is broken because of transformation I chose to show the problem, .reverse(), is changing the array itself. Var a is tracking, .reverse() is changing it, $digest is going, .reverse() is going and on and on. Example need to be a little bit complex and accent on other detail, so I would create different question. Thanks everyone and sorry for not worked out question Commented Dec 31, 2014 at 15:16

4 Answers 4

5

The problem is that you're calling the reverse function in ng-repeat and that $apply and $digest many times. If you're using AngularJS 1.3.x and your data will be created once and will not change at run-time, you can use bind-once property by typing the following in any of ng-(directives)

<body ng-init='a = [1, 2, 3].reverse()'>
   <div ng-repeat="item in ::a">{{item}}</div> 
</body>

prefixing a with :: tells AngularJS that this array or this variable won't be changed, so it will release the $watch function from it and won't consume $digest too many times.

For more information about bind once feature, check this one-time-binding

For the reversing technique itself if it's dynamically created and frequently changed, you can use one of the following approaches:

<body ng-init='a = [1, 2, 3]'>
  <div ng-repeat="item in a.slice().reverse()">{{item}}</div>
</body>

or also you can wrap this into filter, you can use it as follows:

app.filter('reverse', function() {
  return function(items) {
    return items.slice().reverse();
  };
});

and in the HTML type the following line of code:

<body ng-init='a = [1, 2, 3]'>
  <div ng-repeat="item in a | reverse">{{item}}</div>
</body>

for ordering array of objects in general, you should use the following:

<body ng-init='a = [{id: 1}, {id: 2}, {id: 3}]'>
  <div ng-repeat="item in a | orderBy:'id':true">{{item.id}}</div>
</body>

using true for reverse ordering and false for ascending ordering.

You can check also this question and answer for more information: angular ng-repeat in reverse

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

Comments

2

It is because of you calling the reverse() function in the ng-repeat.

Like this it works without errors

<body ng-init='a = [1, 2, 3].reverse()'>
   <div ng-repeat="item in a">{{item}}</div> 
</body>

3 Comments

As I said, this is simplified example, and creation on new collection right inside ng-repeat is a critical part. In my real problem, for example, it was function that except collection and reducing it to new collection
Then you need to give us a better example to analyze.
1

This happens because angular uses a fixed-point model for rendering the objects in the page. When, after applying one iteration, all the "digest" of the objects do not change, the model is considered stable and it is rendered in the view. If the model is not stable after x=10 iterations, then an error is raised. In your case, the function reverse() generate always a new model object with a different digest.

For your particular problem, you can use ng-repeat with the orderBy clause (assuming that the model object is an array).

In general, when you have a main model and many derived sub-models, it is good practice to derive the sub-models using $watch expressions in a "reactive" fashion.

Comments

0

using a function for ng-repeat is not a prefer way, you have to be carefully when using function for ng-repeat items. please check this post.

How to Loop through items returned by a function with ng-repeat?

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.