Friday, October 25, 2013

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):
<div data-ng-app='App'>
    <div data-ng-controller="MyCtrl">
        <form>
            <label for="searchText">Search Text:</label>
            <input data-ng-model="searchText" name="searchText" />
            <br/>
            <input type="checkbox" data-ng-model="throttle">&nbsp;Throttle
            <br/>
            <label>You typed:</label> <span>{{searchText}}</span>
        </form>
        <ul><li data-ng-repeat="item in filteredList">{{item}}</li></ul>
    </div>
</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!

Friday, October 11, 2013

My XML is Alive! An Intro to XAML

I have to admit I have been working with XAML for so long that I tend to take it for granted. That's why I was excited when the Gwinnett Georgia Microsoft Users Group requested a talk that would be an introduction to XAML. It seemed a great way to get back to why XAML is so powerful - and why it's counterparts in the web like AngularJS are so effective. I enjoyed putting the talk together and more importantly had a fantastic time delivering the talk. The talk includes source code that steps through XAML, including a class library that illustrates how XAML instantiates objects even if they aren't "XAML aware", an example of how data-binding would be done manually if it wasn't build into the XAML system, and samples that illustrate the Visual State Manager along with the MVVM pattern.

Here is the description of the talk:

Extensible Application Markup Language, better known as XAML (pronounced “zammel”), is a language developed by Microsoft that is based on XML. It provides a declarative way to instantiate rich object graphs – in other words, through XAML you are able to create instances of classes, set properties, and define behaviors. Most commonly used to describe the user interface for technologies like Silverlight, WPF, and Windows 8.1, XAML provides a separation of concerns between the presentation and business logic for an app and gives the designer the flexibility to create experiences that interact with code through data-binding. This enables design-time data and true parallel workflows between designers and developers. Jeremy Likness will walk you through XAML, including how it is used by various technologies and the advantages it provides when building applications.

You can grab the deck for the talk at SlideShare and the link to the source is on the last slide.

Enjoy!

Jeremy Likness