How Two Way Data Binding works in Angular JS

Two way data binding is one of the most powerful feature in Angular JS.It will help you to save from writing a lots of regular code.

What does it mean by two-way data binding?

In simple words, two way data binding means AngularJs synchronizes the data between the scope model and veiw.
It means if a value of a scope model changes it automatically updates the same value in the view and similarly if the value in the view changes it automaticaly updates the value in the scope model.

How does two way data binding works in Angular JS?

two wayWhen we write an expression ({{dyanvar}}), behind the scenes Angular sets up a watcher on the scope model, which in turn updates the view whenever the model changes. This watcher is like any other watcher we set up in AngularJS:

$scope.$watch('dyanvar', function(newValue, oldValue) {
  //update the view with newValue

The second argument passed to $watch() is known as a listener function, and It is called whenever the value of dyanvar changes.

When the value of dyanvar changes this listener is called, updating the expression in HTML.
But still,How does Angular figure out when to call this listener function? In other words, how does AngularJS know when {{dyanvar}} changes so that it can call the corresponding listener? Does it run a function in a particular interval to check whether the value of the scope model has changed or not ? Well, this is where the $digest cycle comes into the picture.

It’s the $digest cycle where the watchers are fired. When a watcher is fired, AngularJS evaluates the scope model, and if it has changed its value then the corresponding listener function is called. So, Now the question is when and how this $digest cycle starts.

The $digest cycle starts as a result of a call to $scope.$digest(). Assume that we change a scope model in a handler function through the ng-click directive. In that case AngularJS automatically triggers a $digest cycle by calling $digest(). When the $digest cycle starts, it fires each of the watchers. These watchers check if the current value of the scope model is different from last calculated value. If yes, then the corresponding listener function executes. As a result, if you have any expressions in the view they will be updated. In addition to ng-click, there are several other built-in directives/services that let us change models (e.g. ng-model, $timeout, etc) and automatically trigger a $digest cycle.

But Angular doesn’t directly call $digest(). Instead, it calls $scope.$apply(), which in turn calls $rootScope.$digest().
As a result of this, a digest cycle starts at the $rootScope, and subsequently visits all the child scopes calling the watchers along the way.

Now, let’s assume you attach an ng-click directive to a button and pass a function name to it. When the button is clicked,AngularJS wraps the function call within $scope.$apply(). So, your function executes as usual, change models (if any), and a $digest cycle starts to ensure your changes are reflected in the view.

When do we need to use $apply() manually?

If AngularJS usually wraps our code in $apply() and starts a $digest cycle, then when do you need to do call $apply() manually?
Actually, AngularJS makes one thing pretty clear. It will account for only those model changes which are done inside AngularJS’ context Angular’s built-in directives already do this so that any model changes you make are reflected in the view.
However, if you change any model outside of the Angular context,(For example if we update a model using a jquery plugin) then you need to inform Angular of the changes by calling $apply() manually. In these cases either we can call to $apply() or $digest() to kick of a digest cycle for dirty checking , but its always recommended to use $apply() as it has built in error handling mechanism.


2 thoughts on “How Two Way Data Binding works in Angular JS

  1. Very clear and concise explanation of how $digest works, thank you!

    Your post helped me understand why a $log message that I put inside a $scope ‘s model function kept firing when I was interacting with other scopes in my application (like clicking an input field having a ng-click directive attached). I didn’t get why it happened, since the model didn’t actually change.

    $scope.myModel = {

    myFunction: function(){

    $log.log(“Message that gets displayed on each $digest cycle”);

    It seems my $log message was displayed in the console as the $digest loop reevaluated all scope models, looking for changes, including my function’s model. Doh! 🙂


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s