Built-In and Custom AngularJS Filters

Now that you know how to write custom AngularJS directives and how AngularJS helps validate forms, let’s move on to the next great feature. AngularJS filters make it easy to display a subset of items from a collection. They are used with directives like ng-options and ng-repeat. Read this guide to learn how to decipher their syntax and even write your own. 

Built-In Filters

Angular comes with a great set of built-in filters. Without any customization, you can filter a collection based on the values of properties. Filters follow this basic format:

item in items | filter : expression : comparator

Say you have a collection of items with a Boolean property called isDisabled. Display only enabled items with markup like this:

<div ng-repeat="item in items | filter : { isDisabled: false }"> … </div>

Filtering on multiple properties is allowed as well:

<div ng-repeat="item in items | filter : { isDisabled: false, isOpen: true }"> … </div>

Say you want to filter based on a string property. By default, Angular filters compare strings using an approximate, case-insensitive match instead of exact. The following filter will display all items that have a name property containing the letter “A”:

<div ng-repeat="item in items | filter : { name: 'A' }"> … </div>

Need an exact match? Include the comparator parameter to indicate you desire a precise, case-sensitive match. This filter only displays items that have a name equal to “Ares”:

<div ng-repeat="item in items | filter : { name: 'Ares' } : true"> … </div>

Setting this value to false is equivalent to the previous example.

Need even more match customization? The comparator parameter can also be a function that returns true if the expected and actual values are considered equal.

In this example we want an exact match, but we also want case-insensitivity:

<div ng-repeat="item in items | filter : { name: 'Ares' } : myNameComparer"> … </div>
// In your controller
$scope.myNameComparer = function(actual, expected) {
    // Expected = "Ares"
    if (actual.toLowerCase() == expected.toLowerCase()) return true;
    return false;
};

You can even select objects that have at least one property (doesn’t matter which) containing a search string:

<label>Search <input type="text" ng-model="searchStr" />
<div ng-repeat="item in items | filter: searchStr"> … </div>

This technique is known as a full-text search.

Custom Filters

Writing your own filters is a useful skill for all AngularJS developers. A filter is ultimately a function that returns the final set of items. The function’s first parameter is the original set of items, and it allows an arbitrary number of additional parameters. Angular will execute your filter each time one of the function inputs change.

Say you have a collection of trees, and each tree has a collection of states to which the species is native. We only want to display trees that are native to your area. After defining your Angular module, add the custom filter like so:

myModule.filter("byState", () => {
    return (items, state) => {
        var result = [];

        angular.forEach(items, (item, index) => {
            // If tree is native to this state, add it
            if (item.states.indexOf(state) >= 0) 
                result.push(item);
        });

        return result;
    };
});

Utilize this custom filter in the same fashion as a built-in filter:

<h4>Tree species native to <span ng-bind="myState"></span></h4>
<div ng-repeat="tree in trees | byState : myState">
    <span ng-bind=”tree.name”></span> - <i ng-bind=”tree.scientificName”></i>
</div>

Filter with Additional Parameters

As seen previously, you may pass multiple parameters to a filter function by separating them with a colon (:) in the markup. Here is an example of a custom filter that selects animals based on criteria like furriness and diet:

<label>Furry
    <input type="checkbox" name="isFurry" ng-model="isFurry" />
</label>
<label>Herbivore
    <input type="checkbox" name="isHerbivore" ng-model="isHerbivore" />
</label>
<select ng-model="animal" ng-options="a.name for a in animals | byCriteria : isFurry : isHerbivore">
    <option value="">Animals meeting the criteria</option>
</select>
myModule.filter("byCriteria", () => {
    return (animals, isFurry, isHerbivore) => {
        var result = [];

        angular.forEach(animals, (animal) => {
            // Add the item if it meets your criteria
            var add = true;
    
            if ((isFurry != animal.isFurry) 
                || (isHerbivore != animal.isHerbivore)) {
                add = false;
            }

            if (add) result.push(animal);
        });

        return result;
    };
});

Transformative Filters

Filters are most commonly used for selecting a subset of items from a collection, but they can also be used to transform collections, strings, or numbers. Use filters to reorder items, change capitalization, or add formatting.

Easily display numbers in money format using the built-in filter currency:

<span ng-bind="profit | currency"></span>

This filter will display a number like 19.9 as $19.90. Capitalize an entire string using the uppercase filter:

<span ng-bind="warningMessage | uppercase"></span>

Demo

Check out this plunk to view a demo of these concepts.


What other built-in or custom filters do you like to use? Share your wisdom with us in a comment below! To learn more about how we use AngularJS, read Kayla’s other posts: How AngularJS Helps Validate Forms and How To Write Custom AngularJS Directives.

Found this blog post useful? Make yourself comfortable and check out our blog home page to explore other technologies we use on a daily basis and the fixes we’ve solved in our day to day work. To make your life easier, subscribe to our blog to get instant updates sent straight to your inbox:

{{cta(‘33985992-7ced-4ebd-b7c8-4fcb88ae3da4’)}}

Author

Leave a Comment