Explain Codes LogoExplain Codes Logo

Watch multiple $scope attributes

javascript
deep-watching
custom-watchers
performance-optimization
Alex KataevbyAlex Kataev·Dec 6, 2024
TLDR

To handle the monitoring of multiple properties within your AngularJS application efficiently, you'll want to employ the $scope.$watchGroup method:

$scope.$watchGroup(['prop1', 'prop2'], (newVals, oldVals) => { // Put your feet up while Angular handles 'prop1' or 'prop2' changes. });

This solution does the legwork of watching prop1 and prop2 changes, and executes the callback only when either property changes, hence saving the effort, and increasing performance compared to employing individual $scope.$watch methods.

Monitoring deep JSON objects

If you need to keep tabs on changes in nested properties or complete objects, $watch is your trusty sidekick. With the object equality argument, it offers deep watching, like an owl stalking mice at night:

$scope.$watch('deepObject', (newValue, oldValue) => { // Your code doing its night watch right here. }, true);

The setting of true as the third argument is key for observing object equality, not just reference change. Think of it as checking DNA, not just faces.

Creating custom watchers with $watch

For those times when you want pixel-level control, custom getter function with $scope.$watch is your friend. It combines multiple values or involves more complex logic:

$scope.$watch(() => { // Returning Captain Planet by combining all the Planeteers return $scope.earth + $scope.fire + $scope.wind + $scope.water + $scope.heart; }, (captainPlanet, oldCaptainPlanet) => { // The power is yours! });

By using a custom getter, the watch expression gives a composite value – effectively helping monitor changes across multiple scope properties.

Collection watch for performance

Your best choice for performance-sensitive scenarios dealing with arrays or collections would be $watchCollection. This method knows how to watch for changes within arrays or objects:

$scope.$watchCollection('rainbow', (newRainbow, oldRainbow) => { // If the pot of gold is missing at the end, call the leprechaun });

Remember, $watchCollection is powerful, but it's more of a sprinter — doing shallow watching, compared to the endurance runner, the deep watcher in $watch.

Efficient way to observe changes with custom watches

In complex applications with numerous attributes to watch, combine them into a composite watch and respond collectively to changes:

$scope.$watch(() => { return { prop1: $scope.property1, prop2: $scope.property2, prop3: $scope.property3 }; }, (current, previous) => { // When any property gets a haircut, we react }, true); // Set to `true` to ensure we do deep observing like Sherlock Holmes

This approach allows you to keep an eye on separate properties and respond simultaneously when any change occurs, just like a hawk.

Alternatives to watching multiple attributes

Angular's native features like ng-change directives or ng-model options can sometimes obviate the need for deep object watching:

<input type="text" ng-model="prop1" ng-change="handleFn()" /> <input type="text" ng-model="prop2" ng-model-options="{ debounce: 100 }" ng-change="handleFn()" />

Your handleFn fires whenever the input changes, and ng-model-options controls the frequency of these changes for performance optimization. Your watchers can now relax and enjoy their beverages in peace.