AngularJS provides the $scope.$watch()
function to observe changes in scope variables and execute a callback whenever the watched value changes. This is useful for reactive programming where you want to trigger logic based on model updates.
1. Understanding $scope.$watch()
Syntax:
javascriptCopyEdit$scope.$watch(watchExpression, listenerFunction, [deepWatch]);
Parameter | Description |
---|---|
watchExpression | The scope variable or function to watch. |
listenerFunction | Function executed when the watched value changes. |
deepWatch (optional) | true for deep watching of object properties. |
2. Basic Example
var app = angular.module('myApp', []);
app.controller('MyController', function($scope) {
$scope.counter = 0;
$scope.$watch('counter', function(newValue, oldValue) {
console.log("Counter changed from", oldValue, "to", newValue);
});
$scope.increment = function() {
$scope.counter++;
};
});
<div ng-controller="MyController">
<p>Counter: {{ counter }}</p>
<button ng-click="increment()">Increment</button>
</div>
Explanation:
- The
$watch
function trackscounter
. - When
counter
changes, the old value and new value are logged.
3. Watching an Object Property
$scope.user = { name: "John" };
$scope.$watch('user.name', function(newValue, oldValue) {
console.log("User name changed from", oldValue, "to", newValue);
});
Use Case: Detecting specific property changes inside an object.
4. Deep Watching with Objects
If you want to track all properties inside an object, use true
as the third argument.
$scope.user = { name: "John", age: 25 };
$scope.$watch('user', function(newValue, oldValue) {
console.log("User object changed", newValue);
}, true);
Explanation:
- The third argument
true
enables deep watching of all object properties. - Without
true
,$watch
only detects whenuser
is reassigned, not when its properties change.
5. Watching an Expression or Function
Instead of watching a variable, you can watch a function.
$scope.$watch(
function() { return $scope.user.name.length; },
function(newValue, oldValue) {
console.log("Name length changed from", oldValue, "to", newValue);
}
);
Use Case:
- Useful when tracking computed properties or derived values.
6. Using $watchGroup()
to Watch Multiple Variables
Instead of setting up multiple $watch()
calls, use $watchGroup()
for watching multiple variables.
$scope.user = { name: "John", age: 25 }; $scope.$watchGroup(['user.name', 'user.age'], function(newValues, oldValues) { console.log("Name changed from", oldValues[0], "to", newValues[0]); console.log("Age changed from", oldValues[1], "to", newValues[1]); });
Advantages: ✔ Tracks multiple variables at once. ✔ Efficient compared to multiple$watch()
calls.
7. Using $watchCollection()
for Arrays
For shallow watching of arrays or objects, use $watchCollection()
.
$scope.items = ["Apple", "Banana"];
$scope.$watchCollection('items', function(newValues, oldValues) {
console.log("Items changed:", newValues);
});
$scope.addItem = function() {
$scope.items.push("Cherry");
};
When to Use $watchCollection()
?
- When only array length or top-level items matter.
- It does not track nested objects inside the array.
8. When to Use $scope.$watch()
?
When you need to trigger custom logic based on model changes.
When Angular’s two-way data binding is not sufficient.
When working with third-party libraries that modify data.
9. When Not to Use $scope.$watch()
?
Avoid unnecessary $watch()
calls for performance reasons.
Do not use $watch()
for simple UI updates – Angular’s data binding already handles that.
Avoid deep watching on large objects unless necessary.