Throttling Input in AngularJs Applications using UnderscoreJs Debounce

There are numerous scenarios to throttle input so that you aren’t reevaluating your filters every time they change. The more appropriate term is “debounce” because essentially you are waiting for the input to settle before you invoke a function, so you stop bouncing to the server. The canonical case would be a user entering input into a text box to filter a list. If your filter involves some overhead (for example, it is implemented using a REST resource that executes a query on a backend database) you don’t want to keep rerunning and reloading the results while the user is typing. Instead, you want to wait for them to finish typing their filter and then perform the task once.

A simple solution to this problem is here: http://jsfiddle.net/nZdgm/

Let’s assume you have a list ($scope.list) that you expose as a filtered list ($scope.filteredList) based on anything that contains the text typed into $scope.searchText. Your form would look something like this (ignore the throttle checkbox for now):

 

 

 

           

Throttle

{{searchText}}

 

  • {{item}}

 

</div>

The typical scenario is to watch the search text and react instantly. This method handles the filter:

var filterAction = function($scope) {
if (_.isEmpty($scope.searchText)) {
$scope.filteredList = $scope.list;
return;
}
var searchText = $scope.searchText.toLowerCase();
$scope.filteredList = _.filter($scope.list, function(item) {
return item.indexOf(searchText) !== -1;
});
};

The controller asks the scope to $watch like this:

$scope.$watch(‘searchText’, function(){filterAction($scope);});

This will fire every time you type. To settle things down, use the built-in debounce function that comes with UnderscoreJs. The function is simple: pass it a function to debounce with a time in milliseconds. It will delay actually calling the function you pass until at least the time delay has passed since the last time it was passed. In other words, if we use 1 second (which I did in this example to exaggerate the effect) and the function is called repeatedly as I’m typing in the search box, it will not actually fire until I stop typing and wait for at least 1 second.

You may be tempted to simply debounce the filter action like this:

var filterThrottled = _.debounce(filterAction, 1000);
$scope.$watch(‘searchText’, function(){filterThrottled($scope);});


However, this poses a problem. The debounce uses a timer, which ends up outside of Angular’s digest loop, so nothing will be reflected in the UI because Angular doesn’t know about it. Instead, you must wrap it in a call to $apply:

var filterDelayed = function($scope) {
$scope.$apply(function(){filterAction($scope);});
};

Then you can watch it and only react once the input settles:

var filterThrottled = _.debounce(filterDelayed, 1000);
$scope.$watch(‘searchText’, function(){filterThrottled($scope);});

Of course the full example provides a throttle so you can see the difference between the “instant” filtering and the delayed filtering. The fiddle for this again is online at: http://jsfiddle.net/nZdgm/

Enjoy!

Carefully Tuned Databases

Ensuring a database system has been properly designed, implemented, and tuned requires expertise and ongoing management. Atmosera provides managed Database (DB) services designed to help you get the most out of their systems. Our DB experts are available 24x7x365 to perform any task from basic day-to-day maintenance to complex architecture design.

Get reliable administration.

We maintain and proactively troubleshoot your databases 24x7x365.

Drive rapid innovation.

Together we partner to deploy the latest database and storage technology.

Educate support teams.

We actively help your team better leverage your database tools.

“Atmosera has been more than a infrastructure as a service for Navos. Their DBA team have become trusted partners supplementing our internal staff with deep specialized skills. Their experts have helped us drive additional improvements with our other technology partners. Atmosera brings talent to our team that we would not otherwise have access to and they care about our success.”

– Jim Rudnick, Vice President & Chief Information Officer

Stay Informed

Sign up for the latest blogs, events, and insights.

We deliver solutions that accelerate the value of Azure.
Ready to experience the full power of Microsoft Azure?

Atmosera is thrilled to announce that we have been named GitHub AI Partner of the Year.

X