Call Function with Delay When Textbox Changes in AngularJS


Call Function with Delay When Textbox Changes in AngularJS

Can’t seem to google up an example of how this is done.
I have successfully created a textbox that calls a function every time it changes. What I would like to do is only call the function when the user has stopped typing for x milliseconds.
I know how to do it in JQuery using the keyup event, and can probably make it work this way, but want to do it “the Angular Way”.
Maybe it wasn’t clear from the tag or text, but I am using AngularJS, and want to use correct methodology for that framework to create this delay functionality.


Solution 1:

For angular approach can inject $timeout in controller as dependency and use $watch on scope variable you’ve assigned in ng-model.

var timer=false;
$scope.$watch('ModelName', function(){
  timer= $timeout(function(){
      /* run code*/

Solution 2:

There is ng-model-options for this manner

<input id="delayedModel" ng-model="delayedModel" ng-change="callDelayed()" ng-model-options="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }" />

the callDelayed method only calls after 500 ms from typing the last char or on blur

Here is the documentation

Solution 3:

While @charlietfl provided totally acceptable answer I would like to share with you another approach without using $watch method:


<input id="delayedModel" ng-model="delayedModel" ng-change="callDelayed()"/>


    (function (timer, delay) {
        $scope.callDelayed= function () {
            timer = $timeout(function(){

                /* run code*/

            }, delay)
    })(false, 500);

Maybe it’s worth to point out why self-executing anonymous function is used. The main reason is to not pollute controller scope with time and delay variables. In this case they are defined in local function scope.


I’ve also found an interesting AngularJS project called angular-debounce that makes it really easy to achieve same effect. Using debounce directive it’s possible to dealy model update like this:

<input type="text" ng-model="delayedModel" debounce="500"></input>