AngularJS provides $watch
methods to observe changes in scope variables and trigger callbacks. The three primary $watch
methods are:
$scope.$watch()
→ Watches a single scope variable or expression deeply.$scope.$watchCollection()
→ Watches changes to an object’s properties but not deeply nested changes.$scope.$watchGroup()
→ Watches multiple independent variables at once.
This guide will explore these methods in detail, along with examples to demonstrate their differences.
1. $scope.$watch()
(Deep Watching a Single Variable or Expression)
How It Works
- Watches a single variable or an expression.
- Can detect deep changes if the
deep watch
flag (true
) is set. - Triggers the callback when the value changes.
Example – Watching a Single Variable
HTML
<body ng-app="app" ng-controller="MainCtrl">
<input type="text" ng-model="name">
<p>Watched Value: {{ name }}</p>
</body>
JavaScript
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.name = "AngularJS";
$scope.$watch('name', function(newValue, oldValue) {
console.log("Old Value:", oldValue, "New Value:", newValue);
});
});
How It Works
- When the user types in the input field,
$scope.name
changes. $watch()
detects the change and logs the old and new values.
Example – Deep Watching an Object
$scope.user = { name: "John", age: 30 };
$scope.$watch('user', function(newValue, oldValue) {
console.log("User changed:", newValue);
}, true); // Deep watching enabled
Key Points
Watches a single variable or expression.
Can watch deeply nested objects (with true
flag).
Good for tracking changes to simple values or entire objects.
Inefficient for large objects due to deep comparison overhead.
2. $scope.$watchCollection()
(Shallow Watching an Object’s Properties)
How It Works
- Only detects changes to the first-level properties of an object or array.
- Does not track deep changes (i.e., nested properties).
- Efficient for watching objects without deep tracking overhead.
Example – Watching an Object (Shallow Watching)
JavaScript
$scope.user = { name: "John", age: 30 };
$scope.$watchCollection('user', function(newValue, oldValue) {
console.log("User changed:", newValue);
});
How It Works
- If
user.name
oruser.age
changes, the watch is triggered. - However, if
user.address.street
changes, it won’t trigger the watch.
Example – Watching an Array (Detects Add/Remove, Not Deep Changes)
$scope.items = ["Apple", "Banana"];
$scope.$watchCollection('items', function(newVal, oldVal) {
console.log("Array changed:", newVal);
});
- Adding or removing elements triggers the watch.
- Changing an element inside an object (e.g.,
items[0].price = 10
) will NOT trigger the watch.
Key Points
Efficient for tracking changes in object properties or arrays.
Only tracks first-level changes.
Faster than $watch()
with deep watching enabled.
Does not track nested property changes.
3. $scope.$watchGroup()
(Watching Multiple Independent Variables)
How It Works
- Watches multiple individual scope variables at once.
- Triggers the callback when any of the variables change.
- Useful when tracking multiple separate values instead of a single object.
Example – Watching Multiple Variables
JavaScript
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.$watchGroup(['firstName', 'lastName'], function(newValues, oldValues) {
console.log("First Name:", newValues[0], "Last Name:", newValues[1]);
});
How It Works
- If either
firstName
orlastName
changes, the callback executes. - Instead of tracking an object (
$watchCollection()
), it watches separate variables.
Key Points
Tracks multiple independent variables.
More efficient than using multiple $watch()
calls.
Cannot track deep changes within objects.
Comparison Table
Feature | $watch() | $watchCollection() | $watchGroup() |
---|---|---|---|
Watches | Single variable/expression | First-level properties of an object or array | Multiple independent variables |
Detects Nested Changes? | ✅ (if true is passed) | ❌ | ❌ |
Detects Added/Removed Array Items? | ✅ | ✅ | ❌ |
Detects Changes in Primitive Values? | ✅ | ✅ | ✅ |
Performance | Slow (with deep watching) | Faster | Faster |
Use Case | Single object or deep tracking | First-level object properties or arrays | Multiple separate variables |
Which One Should You Use?
- Use
$watch()
when you need deep tracking for an object. - Use
$watchCollection()
when you only care about first-level changes in objects or arrays. - Use
$watchGroup()
when you need to watch multiple individual variables together.