Custom filters in AngularJS

tempFormatAngularJS offers a few built-in filters that were described in one of my previous articles. Mostly, they format data. A number of them is not big. It is pretty small while a range of filters needed in modern applications is quite wide. Fortunately, there is no reason to complain about it too much. A developer can easily create a filter that he/she needs. This article describes how to create a custom filter and use it.

 

A filter is a function that takes an input and statelessly produces an output in a deterministic way. It means that the result should not depend on how many times the filter has been executed before.

 

No parameter filter

For purpose of this post, I will create a filter for converting temperature values between Celsius degrees and Fahrenheit degrees.

A filter is created by executing the filter function on an Angular module. See the below example:

<div ng-app="testApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js" type="text/javascript"></script>
<script type="text/javascript">
// app.js
angular.module('testApp', [
]);

// filters.js
angular.module('testApp')
.filter('celsius', [function() {
return function(celsius) {
if (celsius === undefined || celsius === null) {
return '';
}
return celsius + '°C';
};
}])
.filter('fahrenheit', [function() {
return function(celsius) {
if (celsius === undefined || celsius === null) {
return '';
}
var farenheit = celsius * 1.8 + 32;
return farenheit + '°F';
};
}]);
</script>
<input type="number" ng-model="temperature" />
<p>{{temperature}}</p>
<p>{{temperature | celsius}}</p>
<p>{{temperature | fahrenheit}}</p>
</div>

{{temperature}}

{{temperature | celsius}}

{{temperature | fahrenheit}}


 

There are two filters defined above: celsius and fahrenheit. The first one returns the original value with a unit (°C) added. The second one converts the provided value and returns it with a unit (°F). The filters are used in the same way as Angular built-in filters. The original value for further calculation is passed to the filter as the first parameter of the function.

 

Custom filter with parameter

The above example does not cover all cases. A filter can be parametrized like the currency filter.

<p>{{3456.7843 | currency:"€":0}}</p>       <!-- €3,457 -->

Similar effect can be achieved very easily by adding more arguments to the function in the filter. For example two above filters: celsius and fahrenheit can be replaced by one - temp with a parameter targetUnit that can be celsius or fahrenheit.

<div ng-app="testApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js" type="text/javascript"></script>
<script type="text/javascript">
// app.js
angular.module('testApp', [
]);

// filters.js
angular.module('testApp')
.filter('temp', [function() {
return function(celsius, targetUnit) {
if (celsius === undefined || celsius === null) {
return '';
}
switch(targetUnit) {
case 'celsius':
return celsius + '°C';
break;
case 'fahrenheit':
return celsius * 1.8 + 32 + '°F';
break;
default:
return '';
}
}
}]);
</script>
<input type="number" ng-model="temperature" />
<p>{{temperature}}</p>
<p>{{temperature | temp:'celsius'}}</p>
<p>{{temperature | temp:'fahrenheit'}}</p>
</div>

{{temperature}}

{{temperature | temp:'celsius'}}

{{temperature | temp:'fahrenheit'}}

 

A value that is provided after the colon goes to the filter function as the second argument. The first one is the original value.

Filters are powerful feature of AngularJS. A list of those that are built-in is small enough that sooner or later a need of one or more additional ones becomes true. Luckily, implementing them is very easy and the code still stays well-organized.