Home > Blockchain >  Adding debounce to an input text box with an "ng-keyup" in Angular.js
Adding debounce to an input text box with an "ng-keyup" in Angular.js

Time:04-21

I have this directive for a search box

// Define the search-box
alSH.directive('searchBox',[function(){
      return {
        restrict: 'E',
          template: `
    <input 
      placeholder="Search.." 
      
      ng-keyup=search($evt) 
      ng-model="query"
      ng-model-options="{ debounce: 1000 }"
    />`,
        controller: function SearchBoxController($scope, helper) {
    $scope.query = ''; //ng model
    $scope.search = function() { //this calls in every keyup event
      helper.setQuery($scope.query).search();
    };
    
    helper.setQuery('').search();
  }
    };
}]);

and i tried to use ng-model-options="{ debounce: 1000 }" but still it keeps sending a network request for each key stroke without updating the ng-model probably due to the ng-keyup.
I found this post which asks for something similar but I didn't seem to understand the solution

I have added a codepen demo which has the above code snippet where I'm trying to achieve this behavior

Ideally I would like to limit the number of backend calls sent due to each key stroke. Any idea how to achieve this?

CodePudding user response:

You can do it using a simmilar pattern:

var debounceTimer = false;
$scope.search= function() {
    // if there's already a timeout going, cancel the current one
    if (debounceTimer) {
        $timeout.cancel(debounceTimer);
    }
    // create a new timeout, do your thing when it ellapses
    debounceTimer = $timeout(function() { 
        // ... your action goes here, only if calls are made with at least ONE second interval ...  
        helper.setQuery($scope.query).search();        
    },
    // adjust your time interval accordingly 
    1000);
};

CodePudding user response:

Short answer: use ng-change instead of ng-keyup.

Long answer:

Usually using ng-keyup is just wrong as there are lots of ways input value can be modified (e.g. drag-drop), also some keys will not modify input value, e.g. Esc key. Thats why u should be always careful with just using keyup and better use input change events.

If you use ng-model you should require ngModel directive, inject and use ngModelCtrl. That's what ng-change is doing for you: https://github.com/angular/angular.js/blob/9bff2ce8fb170d7a33d3ad551922d7e23e9f82fc/src/ng/directive/ngChange.js

In simple scenarios you dont need to know all that and you can stick to ng-change ng-model-options, for very specific cases with some weird debounce/throttle/whatever logic when built-in possibilities are not enough, you write custom e.g. my-change directive which works similar way.

  • Related