angularjsangularjs-watch

Remove $watch and bring the logic out of the $watch in AngularJS


I have a code in AngularJS which looks like below :

$scope.startWatching = function () {
    return $scope.$watch('form', function (n, o) {
        var timeoutPromise;

        $timeout.cancel(timeoutPromise);  //does nothing, if timeout alrdy done
        timeoutPromise = $timeout(function () {
            if (n !== o) {
                if ($scope.isLegacy) {
                    $scope.showCompleteBtn = $scope.showCompleteButton2();
                } else {
                    $scope.showCompleteBtn = $scope.showCompleteButton();
                }
            }
        }, 400);



    }, true);

So whenever form changes, either $scope.showCompleteButton2() is called or $scope.showCompleteButton() is called.

The problem is that the $watch() gets called many number if times, so I need to bring these two methods out of the $watch().


Solution

  • Watchers like event listeners should only be added once when the DOM is built. And removed when the DOM is torn down.

    If the code needs to enable or disable the actions performed by the watcher, provide a state in the model to do so:

    var enableWatch = false;
    
    $scope.startWatching = function () {
        enableWatch = true;
    };
    
    var timeoutPromise;
    
    $scope.$watch('form', function (n, o) {
        if (!enableWatch) return;
    
        //ELSE
        timeoutPromise && $timeout.cancel(timeoutPromise);
        timeoutPromise = $timeout(function () {
            if (n !== o) {
                if ($scope.isLegacy) {
                    $scope.showCompleteBtn = $scope.showCompleteButton2();
                } else {
                    $scope.showCompleteBtn = $scope.showCompleteButton();
                }
            }
        }, 400);
    
    }, true);
    

    The watcher ignores changes when the enableWatch variable is false. Set the variable to true to enable the specified actions.