When you want to use $scope.$watch to monitor changes to a variable in AngularJS you may not want to execute the watch on every scope change, so you need to use debounce. A debounce function limits the rate at which a function can fire.
You can use Underscore.js but you may not want to include the underscore library in your app in which case below is a angular version of debounce.
//angularjs debounce
app.factory('debounce', function($timeout) {
return function(callback, interval) {
var timeout = null;
return function() {
$timeout.cancel(timeout);
timeout = $timeout(function () {
callback.apply(this, args);
}, interval);
};
};
});
All you do is wrap the $watch listener in the debounce. The usage for $scope.$watch is:
$watch(watchExpression, listener, [objectEquality]);
In the below example you want to watch the products array for changes and increment a counter with a debounce of 1 second. The products data is displayed in a form using ng-repeat.
//define initial values
$scope.products = []; // products array populated with data from a service
$scope.productChanges = 0;
//watch products for changes with 1 second debounce to
//prevent every keystroke incrementing productChanges
$scope.$watch('products', debounce(function() {
$scope.productChanges++;
},1000), true);
Thanks for the solution.
There’s one thing regarding the args variable: it should be arguments and not args.
or maybe you forgot
var args = Array.prototype.slice.call(arguments);
or maybe you forgot
var args = Array.prototype.slice.call(arguments);