AngularJS

Filters

Your First Filter

Filters are a special type of function that can modify how something is printed out to the page, or can be used to filter an array, or a ng-repeat action. You can create a filter by calling the app.filter() method, passing it a name and a function. See the examples below for details on syntax.


For example, let’s create a filter that will change a string to be all uppercase (essentially a wrapper of the .toUpperCase() javascript function):

var app = angular.module("MyApp", []);

// just like making a controller, you must give the
// filter a unique name, in this case "toUppercase"
app.filter('toUppercase', function(){
    // all the filter does is return a function,
    // which acts as the "filtering" function
    return function(rawString){
        // The filter function takes in the value,
        // which we modify in some way, then return
        // back.
        return rawString.toUpperCase();
    };
}); 

Let’s take a closer look at what’s happening above.

First, we’re creating a filter called “toUppercase”, which is just like a controller; app.filter(...). Then, that filter’s function returns the actual filter function. That function takes a single object, which is the object to be filtered, and should return the filtered version of the object.

Note: In this situation, we’re assuming the object being passed into the filter is a string, and therefore know to always use the filter only on strings. That being said, a further improvement to the filter could be made that loops through the object (if it’s an array) and then makes every element that is a string uppercase.

Now let’s use our new filter in action. Our filter can be used in two ways, either in an angular template or as a javascript function (as an injected Angular reference).

Javascript

Simply inject the angular $filter object to your controller, then use that to retrieve the filter function using its name.

app.controller("MyController", function($scope, $filter){
    this.rawString = "Foo";
    this.capsString = $filter("toUppercase")(this.rawString);
});

HTML

For an angular directive, use the pipe (|) symbol followed by the filter name in the directive after the actual string. For example, let’s say we have a controller called MyController that has a string called rawString as a element of it.

<div ng-controller="MyController as ctrl">
    <span>Capital rawString: {{ ctrl.rawString | toUppercase }}</span>
</div>

Editor’s Note: Angular has a number of built in filters, including “uppercase”, and the “toUppercase” filter is intended only as a demo to easily show off how filters work, but you do not need to built your own uppercase function.

Custom filter to remove values

A typical use case for a filter is to remove values from an array. In this example we pass in an array and remove any nulls found in it, returning the array.

function removeNulls() {
    return function(list) {
        for (var i = list.length - 1; i >= 0; i--) {
            if (typeof list[i] === 'undefined' ||
                    list[i] === null) {
                list.splice(i, 1);
            }
        }
        return list;
    };
}

That would be used in the HTML like

{{listOfItems | removeNulls}}

or in a controller like

listOfItems = removeNullsFilter(listOfItems);

Custom filter to format values

Another use case for filters is to format a single value. In this example, we pass in a value and we are returned an appropriate true boolean value.

function convertToBooleanValue() {
    return function(input) {
        if (typeof input !== 'undefined' &&
                input !== null &&
                (input === true || input === 1 || input === '1' || input
                        .toString().toLowerCase() === 'true')) {
            return true;
        }
        return false;
    };
}

Which in the HTML would be used like this:

{{isAvailable | convertToBooleanValue}}

Or in a controller like:

var available = convertToBooleanValueFilter(isAvailable);

Performing filter in a child array

This example was done in order to demonstrate how you can perform a deep filter in a child array without the necessity of a custom filter.

Controller:

(function() {
  "use strict";
  angular
    .module('app', [])
    .controller('mainCtrl', mainCtrl);

  function mainCtrl() {
    var vm = this;
  
    vm.classifications = ["Saloons", "Sedans", "Commercial vehicle", "Sport car"];
    vm.cars = [  
       {  
          "name":"car1",
          "classifications":[  
             {  
                "name":"Saloons"
             },
             {  
                "name":"Sedans"
             }
          ]
       },
       {  
          "name":"car2",
          "classifications":[  
             {  
                "name":"Saloons"
             },
             {  
                "name":"Commercial vehicle"
             }
          ]
       },
       {  
          "name":"car3",
          "classifications":[  
             {  
                "name":"Sport car"
             },
             {  
                "name":"Sedans"
             }
          ]
       }
    ];
  }
})();

View:

<body ng-app="app" ng-controller="mainCtrl as main">
  Filter car by classification:
  <select ng-model="classificationName"
          ng-options="classification for classification in main.classifications"></select>
  <br>
  <ul>
    <li ng-repeat="car in main.cars |
                   filter: { classifications: { name: classificationName } } track by $index"
                  ng-bind-template="{{car.name}} - {{car.classifications | json}}">
    </li>
  </ul>
</body>

Check the complete DEMO.

Using filters in a controller or service

By injecting $filter, any defined filter in your Angular module may be used in controllers, services, directives or even other filters.

angular.module("app")
  .service("users", usersService)
  .controller("UsersController", UsersController);

function usersService () {
  this.getAll = function () {
    return [{
      id: 1,
      username: "john"
    }, {
      id: 2,
      username: "will"
    }, {
      id: 3,
      username: "jack"
    }];
  };
}

function UsersController ($filter, users) {
  var orderByFilter = $filter("orderBy");

  this.users = orderByFilter(users.getAll(), "username");
  // Now the users are ordered by their usernames: jack, john, will

  this.users = orderByFilter(users.getAll(), "username", true);
  // Now the users are ordered by their usernames, in reverse order: will, john, jack
}

Accessing a filtered list from outside an ng-repeat

Occasionally you will want to access the result of your filters from outside the ng-repeat, perhaps to indicate the number of items that have been filtered out. You can do this using as [variablename] syntax on the ng-repeat.

<ul>
  <li ng-repeat="item in vm.listItems | filter:vm.myFilter as filtered">
    {{item.name}}
  </li>
</ul>
<span>Showing {{filtered.length}} of {{vm.listItems.length}}</span>

This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow