Angular ng-change delay

76,590

Solution 1

AngularJS 1.3+

Since AngularJS 1.3 you can utilize the debounce property ngModelOptions provides to achieve that very easy without using $timeout at all. Here's an example:

HTML:

<div ng-app='app' ng-controller='Ctrl'>
    <input type='text' placeholder='Type a name..'
        ng-model='vm.name'
        ng-model-options='{ debounce: 1000 }'
        ng-change='vm.greet()'
    />

    <p ng-bind='vm.greeting'></p>
</div>

JS:

angular.module('app', [])
.controller('Ctrl', [
    '$scope',
    '$log',
    function($scope, $log){
        var vm = $scope.vm = {};

        vm.name = '';
        vm.greeting = '';
        vm.greet = function greet(){
            vm.greeting = vm.name ? 'Hey, ' + vm.name + '!' : '';
            $log.info(vm.greeting);
        };
    }
]);

-- OR --

Check the Fiddle

Before AngularJS 1.3

You'll have to use $timeout to add a delay and probably with the use of $timeout.cancel(previoustimeout) you can cancel any previous timeout and run the new one(helps to prevent the filtering to be executed multiple times consecutovely within a time interval)

Here is an example:

app.controller('MainCtrl', function($scope, $timeout) {
    var _timeout;

    //...
    //...

    $scope.FilterByName = function() {
        if(_timeout) { // if there is already a timeout in process cancel it
            $timeout.cancel(_timeout);
        }
        _timeout = $timeout(function() {
            console.log('filtering');
            _timeout = null;
        }, 500);
    }
});

Solution 2

You could use $timeout to add a delay and probably with the use of $timeout.cancel(previoustimeout) you can cancel any previous timeout and run the new one(helps to prevent the filtering to be executed multiple times consecutovely within a time interval)

Example:-

app.controller('MainCtrl', function($scope, $timeout) {
  var _timeout;

 //...
 //...

  $scope.FilterByName = function () {
    if(_timeout){ //if there is already a timeout in process cancel it
      $timeout.cancel(_timeout);
    }
    _timeout = $timeout(function(){
      console.log('filtering');
      _timeout = null;
    },500);
  }
 });

Plnkr

Solution 3

I know the question is too old. But still want to provide one quicker way to achieve this using debouncing.

So the code can be written as

<input ng-model="xyz" ng-change="FilterByName()" ng-model-options="{debounce: 500}"/>

Debounce will take the number in milliseconds.

Share:
76,590
MGot90
Author by

MGot90

Updated on November 02, 2020

Comments

  • MGot90
    MGot90 over 3 years

    I have an input which filters a ng-repeat list on change. The repeat contains a lot of data and takes a few seconds to filter through everything. I would like their to be 0.5 second delay before I start the filtering process. What is the correct way in angular to create this delay?

    Input

     <input ng-model="xyz" ng-change="FilterByName()" />
    

    Repeat

     <div ng-repeat"foo in bar">
          <p>{{foo.bar}}</p>
     </div>
    

    Filter Function

     $scope.FilterByName = function () {
          //Filtering Stuff Here
     });
    

    Thanks

  • Vincent Sels
    Vincent Sels over 9 years
    Note that ng-model-options was only added in Angular v1.3 (and the debounce property in beta.8). Those who still need to use an older version of Angular will have to resort to other solutions, like the one from PSL, or by using an external module like ng-debounce.
  • PSL
    PSL almost 9 years
    To the downvoter and future visitors: This answer was added for Angular 1.2.x, and added probably before 1.3.x was released which has the the debounce option with ng-model-options and never got a chance to revise the answer before a better answer from @rckd came in (around 3 months after this one).
  • SStanley
    SStanley over 8 years
    Even though I am using angular js 1.4 I still find the $timeout solution useful with ng-change when I don't want to debounce the model.
  • Johan Baaij
    Johan Baaij almost 8 years
    A downside could be that this seems to delay validations like ng-pattern as well.