Understanding Watchers in AngularJS

Last modified: February 20, 2019

Ask all your coding questions @ codequery.io

Update: Watchers are important to understand because they represent such a major inefficiency in the original AngularJS.

It's because of watchers that the new Angular surfaced.

It's highly recommended that you start using the newer version of Angular. Check out these to get a quick taste for how Angular works today.

The 5 Minute Guide to Making HTTP Requests in Angular

Angular Form Examples

Anyone whose used Angular 1 knows how easy it makes two-way data binding. By simply throwing ng-model on an input tag, the view is able to dynamically update it's underlying data model. This provides a great advantage to developers as the presentation layer is directly linked to the app's state. Developers no longer have to worry about callbacks, event handlers, or service calls to keep views in sync with the data they represent.

While such functionality is standard with Angular 1, it can severely hinder performance if you don't know what's going on under the hood. In fact, Angular 2 takes a fundamentally different approach to data binding because of the issues seen with Angular 1's performance.

This is not to say that Angular 1 shouldn't be used. The framework is still widely used and growing in popularity. If you take advantage of Angular's two-way data binding however, it's important to understand how this magic really works. This article explores AngularJS $$watchers and how they work with the Angular digest cycle to keep views constantly synced with data models.

What are watchers?

Any time you use a built-in Angular directives (such as ng-show, ng-if, ng-repeat), you are creating a watcher. Take the following code bit:

<div ng-show='isMine'>

By using Angular's ng-show directive, you create a watcher for the parent $scope object. In this case, your app is now 'watching' for changes to the scope's isMine variable. Similarly, if you have:

<div ng-show='isMine'>

then there is an additional watcher for the myVar scope variable. Any time you reference a scope variable in an ng-* or use the double brackets {{ }} you create another watcher for the scope.

The digest cycle

So what? Why do watchers matter in our Angular apps? The answer is found in Angular's digest cycle. This cycle is really a function that repeatedly checks for changes in the 'watchers' we've defined for a given scope. With every watcher you create, a corresponding watcher function is added to the digest loop. This function executes every time the cycle runs, comparing the watcher's old value with it's new value. The cycle runs once to check for initial changes, and then a second,third,fourth time until all watchers stop changing.

The digest cycle is what makes two-way data binding possible in Angular 1. It's also what causes the majority of Angular 1's performance issues. It should be noted that the digest cycle runs every time the app's state changes. You may see the $digest() or $apply() functions used. These manually trigger the digest cycle, however Angular based DOM manipulations, AJAX calls, and callbacks automatically fire the cycle as well.

How many watchers is too many?

When considering how often the digest cycle runs, it's easy to see how watchers can slow your app down. This doesn't mean you shouldn't use watchers. Besides, what's the point of using the Angular library if you can't take advantage of the two-way data binding?

As a general rule, you should try keeping the number of watchers for any given view in the hundreds. Remember that this will include not only the current scope but any children scopes as well. A few hundred watchers may seem like a lot, but consider the following:

<div ng-repeat='row in table'>

Not only are we defining a watcher with ng-repeat, we are also defining a watcher for every iteration of the {{row}} expression. This means that with just 100 data table rows we would already have 100+ watchers for this scope!


While watchers can get out of hand fast, you'd be surprised as to how many watchers you can have without impacting performance. This is not to say that excessive watchers won't slow you down. Be especially careful with nested ng-repeat's when using Angular 1's two-way data binding. Also remember that frameworks like Angular 2 and React take more efficient approaches to data binding and are worth exploring for future projects.


August 11, 2017
watchers represent the main vulnerability with angular 1. angular 2 removes the concept of watchers with unidirectional data flow. it's important to remember that watchers are only necessary when you have bidirectional data flow. with angular 2, every change propagates from the root component down. this gives the framework better control over change detection while improving performance. great discussion on watchers and how they contribute to angular 1 magic though :).
August 2, 2017
i think it is important to understand watchers even if you use Angular 2. watchers are fundamental to how Angular 1's digest cycle worked. if you can understand how this caused problems with 1 then you will better appreciate the improvements with change detection in 2....
August 2, 2017
if you still use Angular 1 then this is a great read. if you have moved on to the more modern (and much improved) angular 2 then completely ignore this article. watchers aren't a thing in Angular 2 and Angular 2 uses unidirectional data flow and change detection like react.
July 13, 2017
great read..
Brad B.
June 20, 2017
watchers are everything in terms of performance. with the advent of React, Angular 1 has been clearly labeled as less efficient (mainly because of watchers). if you are going to use angular 1, you best be watching those watchers :).
June 5, 2017
May 16, 2017
May 11, 2017
this article does a great job of explaining why angular 1 should never be used. while two-way data binding used to be the talk of the town, front end guys are starting to get wise with react, angular 2, etc. don't use angular 1...
Kumariv K.
May 1, 2017
watchers are one of the hardest things to understand with Angular 1. they aren't as expensive as people typically think..browsers are powerful things these days. it is true however that for every $scope variable you define, you are going to generate a watcher. When you add these up (especially with pages rendering thousands of records via ng-repeat etc) you are going to start running into performance issues. As pointed out in the article, Angular 2 addresses this and should be used moving forward. angular 1 is a great way to get started with the SPA world though.
April 19, 2017
once you realize what watchers are doing you will realize that Angular 1 is not the right way to do things these days..frameworks like React and Angular 2 are following more of the flux (one way data flow) architecture and abandoning classic MVC..this is making front end SPA's much better performance wise.
Robbie Eisenhower
March 18, 2017
once you fully understand how watchers work in Angular 1, you will realize why Angular 1 is quickly becoming a thing of the past...
Timmy Vanderkamp
March 16, 2017
$watchers are a very inefficient way to handle change control. moving forward look at react and Angular 2. they both make great use of the shadow DOM and completely eliminate the need for digest cycle, watchers etc.
Tom Berbank
December 22, 2016
agreed. a great explanation on AngularJS watchers and what they are all about...
Sam Erickson
December 22, 2016
great read!

You might also like: