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);