Intoduction to $apply() Function and the $digest Loop in angularjs

Let’s take a look at a very simple angularjs snippet where you start typing your name into an input field. There is also a div that shows what you typed, in real time:

<input id="input" type="text" ng-model="name"/>
<div id="output">{{name}}</div>

You already know what expressions like {{name}} do—they provide a unidirectional binding from model to view. Whenever the name model changes the expression automatically updates itself. Is some kind of magic behind this? No. It’s done just by setting up a watcher on the name model. The expressions are a special type of directive that set up a watcher on models or functions—something we did in the last section. But their purpose is to get notified when the value of the model changes and update the DOM accordingly.

This is only half of the story, however. How does Angular know when a model changes and calls its corresponding watcher? Does it run a function in an interval to check if the model value has changed? If I make an AJAX call and update my model with the response will Angular know about it?

An angularjs $scope has a function called $apply() which takes a function as an argument. angularjs says that it’ll know about model mutations only if that mutation is done inside $apply(). So, you simply need to put the code that changes models inside a function and call $scope.$apply(), passing that function as an argument. After the $apply() function call ends, angularjs knows that some model changes might have occurred. It then starts a digest cycle by calling another function—$rootScope.$digest()―which propagates to all child scopes. In the digest cycle all the watchers are called to check if the model value has changed. If a value has changed, the corresponding listener function then gets called. Now it’s up to the listener how it handles the model changes. The watcher set up by an expression ({{}}) updates the DOM with the new value of the model. In our previous example, we showed an alert when the model reached a value of 2.

But what if the listener function of the watcher itself changes any model? How does angularjs account for that change? Actually, the digest cycle doesn’t run only once after the $apply() call. After calling the listener functions, the digest cycle starts all over again and fires each watcher to check if any of the models have been mutated in the last loop. If any change is found, the corresponding listener is called as usual and, if none of the models have changed, the digest cycle ends. Otherwise, the digest cycle continues to loop until no model changes have been detected or it hits the maximum loop count of 10 (whichever comes first). The digest cycle will not run more than 10 times. So, it’s good to refrain from making model mutations in the listener functions.

Note: The $digest() cycle Always Runs at Least Twice

At a minimum the $digest() cycle runs twice even if there are no model mutation in the listener functions. The cycle runs once more to make sure the models are stable and no change has been made in last loop. This is called dirty checking.

About the author

Deven Rathore

I'm Deven Rathore, a multidisciplinary & self-taught designer with 3 years of experience. I'm passionate about technology, music, coffee, traveling and everything visually stimulating. Constantly learning and experiencing new things.

Pin It on Pinterest

Shares