Fix Angular's digest iterations errors with memoization
Sometimes I have failed Angular code with the following exception message: Error: 10 $digest() iterations reached. Aborting! and I had no idea what is going on there while didn’t get an explanation how Angular’s bindings work. In this article I will share an idea how to avoid the problem and how to get better performance in Angular applications with memoization technique.
The $digest problem
So, when you get the error message Error: 10 $digest() iterations reached. Aborting! in your Angular application what it actually means? Well, to answer on the question we have to understand how Angular detects changes to show them on UI immediately.
The algorithm is very simple - when you output a variable or function in html templates via bindings, a watcher is created. During life cycle of the application, the watchers’s expressions are called many times and their results matched with the previous values, and, if values differ, an event is fired about this and the new values shown in the templates. To get more information about detecting the changes you can refer this article. But for now it’s enough to understand that the possible issue is a function which returns an array of objects and the function is called in the digest cycle.
It’s very simple to demonstrate it. Assume that we want to iterate through users list which is generated in a controller’s function:
The issue happens because the
getUsers() returns different result every call despite of the fact that properties of the array items are the same:
That’s why Angular’s digest cycle will infinitely call the
getUsers. The error message Error: 10 $digest() iterations reached. Aborting! informs us about this.
To fix the problem we can cache the results of the function. For this purpose I prefer to use Lo-Dash’s memoize function:
Using this technique we improve performance of our Angular application, get rid of exception Error: 10 $digest() iterations reached. Aborting!, implement functions on
$scope which return an array of objects and the functions can be used in Angular’s templates.