← all articles

Build custom filters with AngularJS

Tamas Piros | 15 January 2016

What are AngularJS filters?

Let's take a look at how filters work - there is a built in filter that showcases what filters can do for you and that is the 'currency' filter. It's easy to understand yet gives you a powerful mechanism to transforming numbers into currency values - meaning that a regular number will become properly formatted with the currency symbol appended to it as well.

    <div ng-init="amount = 1250.90">
      <span>Your final amount is: {{ amount | currency}}</span>
    </div>

Running the above example will produce $1,250.90 automatically formatting the number as well as the currency symbol based on your locale settings. We can of course overwrite these settings by passing in an option to the currency filter:

    <div ng-init="amount = 1250.90">
      <span>Your final amount is: {{ amount | currency:"£"}}</span>
    </div>

The above will return £1,250.90.

(Please note that if you an “” symbol appearing just before the £ sign just add <meta charset="utf-8"> into your HTML file between the <head> and <title> tags to indicate the that you wish to see the content of your HTML file in UTF8 encoding. This has nothing to do with Angular, it’s a character encoding issue.)

Creating custom filters in AngularJS

The fact that developers can create custom filters opens up quite a few possibilities. In this article we are going to explore a few examples starting by probably what is the easiest filter of all: accepting a word as an input and producing its reverse form. Filters are standard JavaScript functions therefore you can literally do anything in them that JavaScript permits.

angular.module('myApp', [])
.controller('MyCtrl', MyCtrl)
.filter('reverse', reverse);

function reverse() {
 return function(string) {
   if (string) {
     return string.split('').reverse().join('');
   }
 }
}

In the above code we specify an Angular application, a controller and a custom filter with the name 'reverse' and we assign the a function to it with the same name. In the function definition itself we return a function that takes a string (that is the bound value before the | (pipe) symbol) and we reverse it.

<div ng-app="myApp" ng-controller='MyCtrl as vm'>
  {{ "hello" | reverse}}
</div>

The above will output olleh.

Let's take a look at bit more useful example. How about working with ordinal numbers? The idea here is to add the ‘st’, ‘nd’, ‘rd’ and ‘th’ annotations to numbers. If this functionality is something that you’d like to use application-wide it makes sense to create a filter for it and use it if and when needed.

Here’s a filter that would achieve this:


angular
.module('app', [])
.controller('MyCtrl', MyCtrl)
.filter('dateSuffix', dateSuffix);

function MyCtrl() {}

function dateSuffix($filter) {
  var suffixes = ['th', 'st', 'nd', 'rd'];
  return function(input) {
    if (input) {
      var dtfilter = $filter('date')(input, 'dd MMMM yyyy @ H:m:s');
      var day = parseInt(dtfilter.substr(0,2));
      var relevantDigits = (day < 30) ? day % 20 : day % 30;
      var suffix = (relevantDigits <= 3) ? suffixes[relevantDigits] : suffixes[0];
      dtfilter = dtfilter.substring(2);
      return day + suffix + dtfilter;
    }
  };
}

And use it:

<body ng-controller="MyCtrl">
  <!-- outputs 1st January 2016 -->
  <p>{{ "01 January 2016" | dateSuffix }}</p>
  <!-- outputs 2nd January 2016 -->
  <p>{{ "02 January 2016" | dateSuffix }}</p>
  <!-- outputs 3rd January 2016 -->
  <p>{{ "03 January 2016" | dateSuffix }}</p>
  <!-- outputs 10th January 2016 -->
  <p>{{ "10 January 2016" | dateSuffix }}</p>
</body>

The possibilities are really endless. How about a directive that checks the validity of a credit card and also determines its type? What about capitalising every letter in a sentence after the period?

Free email mini-course on
Full Stack development

Sign up now to receive a free email mini-course covering the MEAN stack and more. Also be the first to know when we release new courses and videos.