I was wondering whether or not it is possible to implement a slight delay on $scope.$watch. I have the following which queries the server, so I'd like to implement a slight delay before it evaluates the query
before querying the server. I've noticed that if you type to quickly it gets confused and doesn't send the correct information:
$scope.$watch("query", function () {
$scope.loading = true;
returnFactory.query($scope.query).then(function (returns) {
$scope.returns = returns;
$scope.loading = false;
});
});
The $timeout service can be used to call another JavaScript function after a given time delay. The $timeout service only schedules a single call to the function. For repeated calling of a function, see $interval later in this text.
This '$timeout' service of AngularJS is functionally similar to the 'window. setTimeout' object of vanilla JavaScript. This service allows the developer to set some time delay before the execution of the function.
The angular JS $watch function is used to watch the scope object. The $watch keep an eye on the variable and as the value of the variable changes the angular JS $what runs a function. This function takes two arguments one is the new value and another parameter is the old value.
The $scope in an AngularJS is a built-in object, which contains application data and methods. You can create properties to a $scope object inside a controller function and assign a value or function to it. The $scope is glue between a controller and view (HTML).
We can also change the delayed time of the block by double clicking on the delay block and changing the value parameter in the delay block. The delayed output with a different delay time is shown in the figure below,
$scope.$watch(function() {}, function() {} ); The first function is the value function and the second function is the listener function. The value function should return the value which is being watched. AngularJS can then check the value returned against the value the watch function returned the last time.
Now let’s apply the delay function on the input step. For that purpose, open the commonly used blocks section of the library browser and select the delay block as shown in the figure below,
This is totally fine; but, it's important to understand why this works and what implications it has for Controller-View coupling and, especially, for $scope.$watch () expressions within your controller and your directive linking functions. Run this demo in my JavaScript Demos project on GitHub. First, let's get rid of some of the magic.
Normally i'd say use angular's $timeout for this delay but you cant clear this timeout yet.
//EDIT:you can.
Set a timeout and clear it, if this watcher gets triggered fast enought.
Like this:
var timeoutCode;
var delayInMs = 2000;
$scope.$watch("query", function(query) {
clearTimeout(timeoutCode); //does nothing, if timeout alrdy done
timeoutCode = setTimeout(function(){ //Set timeout
$scope.loading = true;
returnFactory.query(query).then(function(returns) {
$scope.returns = returns;
$scope.loading = false;
});
},delayInMs);
});
http://jsfiddle.net/4FuyY/
UPDATE Thanks to stewie this can be achieved with angular's $timeout.
var timeoutPromise;
var delayInMs = 2000;
$scope.$watch("query", function(query) {
$timeout.cancel(timeoutPromise); //does nothing, if timeout alrdy done
timeoutPromise = $timeout(function(){ //Set timeout
$scope.loading = true;
returnFactory.query(query).then(function (returns) {
$scope.returns = returns;
$scope.loading = false;
});
},delayInMs);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With