Custom Pipes in Angular
Overview
Multiple built-in pipes exist in the Angular framework. Basic needs could be sufficed using these pipes like uppercase, lowercase, number, json, date, etc. If you need your custom reusable pipe, you can create one. It can be reusable across applications.
Brief Introduction
The angular pipe is similar to the AngularJS filter. Ultimately pipe is a transformation function that takes the value as an input and returns the formatted output. Output can be string, object, or collection. When you are working on real-world applications, you would have to create custom pipes that can solve an application-specific problem. These pipes can be easily reused across the application.
Creating Pipes for Custom Data Transformations
You can create your custom pipe if the set of provided built-in pipes doesn't fulfill the requirement you need. The custom pipe can be used for multiple purposes:
- Simple value transformation
- Change the complete object structure
- Filter the collection based on search criteria changes.
Let's assume we have a time in milliseconds, we had to display the milliseconds in a human-readable format.
Below be an expectation for a custom pipe
Input | Output |
---|---|
4000ms | 4 sec |
60000ms | 1 min |
93000ms | 1 min 33 sec |
3671000 | 1 hr 1 min 11 sec |
Marking a Class as a Pipe
First thing first, we will make a class with the name TimePipe. To perform the TimePipe class as a pipe, we will put the @Pipe decorator on top of it along with name: 'time' in its metadata option.
Using the PipeTransform Interface
Each custom pipe implements a PipeTransform interface. What it means is, we have to implement the transform method.
Usage
Output
4 sec
Inside a transform function, we received the first parameter as an input i.e. value on which pipe is applied, here it's 4000. If you look at the transform method implementation.
- We check if the input value is less than 1 then return 0 sec
- Otherwise we operate input / 1000
Essentially TimePipe converts milliseconds to seconds. So far current implementation takes care of ms to sec. Let's extend the implementation
In the transform function what we have done is
- First calculated days, and the updated remaining
- Then calculated the hour, minute, and seconds.
- After each calculation kept the result in the output variable.
- At the end returned output value ' ' separated.
Now we can easily estimate the result. For eg. {{ 3671000 | time }} would result in the output of 1 hr 1 min 11 sec.
We can improve further, the readability of pipe by defining time and its corresponding assignment, like
And then we can use the same pipe in the transform implementation
Fantastic! Now we want to amend a functionality, and want to extend it by adding values into maps like week, month, and year.
Examples for Better Understanding
We can take more examples to understand the custom pipes in detail. We're going to take two kinds of examples.
- Transformation of a value
- Filter the collection
1. Transformation of a Value
Assume a case of converting milliseconds to a specific format. To the pipe, a specific format will be passed based on that it will take the decision of formatting, and return the output.
Input | format | Output |
---|---|---|
86400000 | 'day' | 1 day |
60000ms | 'min' | 1 min |
60000ms | 'sec' | 60 sec |
The above refers maps collection that we've seen a few moments ago. The second parameter of the transform function is whatever we passed as a value to the pipe. Right after pipeName, we can pass multiple parameters to the pipe separated by :(colon).
Usage
Output
2. Filter the Collection
Suppose we have a page that displays the list of employees. Later we will implement filtering by using Pipe.
app.component.ts
app.component.html
Output
The above code helps to display an employee list. Now if the user types anything inside the Query input box, it should filter results that appear on the table. We would be writing a filter for that.
FilterPipe
Register FilterPipe in AppModule's declarations before using it.
Usage of filter
So any changes in query ngModel, it calls the filter pipe's transform function.
Output
Types of Pipes
There are two kinds of pipe. Pure and impure. By default, any pipe created is pure. Otherwise, you have to mention pure: false in the Pipe metadata options.
Pure
A pure pipe will be called only when Angular detects a change in the source value or the parameters passed to a pipe (i.e. after pipeName on HTML).
Impure
An impure pipe is called for every change detection cycle, even if the value or parameter(s) did not change.
When to Use Pure and Impure Pipe?
We've just built and filter pipe. It has been used to filter the employees list based on query input. Yes! it worked completely as expected. Filtering worked like a CRISP!
Now we would add a record into the employees collection. For that, we will add an Add button, which will push a new employee into the employees collection.
If you look at the above giff, there is an issue. When we filter Newly Added text in the input box. It filters the result the first time, but later when we add more items to employees list. It doesn't reflect. Think a bit about what could have gone wrong 🤔?
It was due to pure: true. Our filter pipe only executes when input or its parameter changes. In a recent case, we were neither changing the input nor the parameters. Hence we did not see Newly Added elements in the filtered list. To fix the issue we can convert the pipe to an impure pipe.
There is a real need of using an impure pipe over a pure pipe. Think about the situation that you need and accordingly use the pipe type.
General Difference Between Pure and Impure Pipes
Pure pipe | Impure pipe |
---|---|
The pipe is executed only when there are changes in value or its object reference | The pipe is executed on every change detection cycle irrespective value changed or not |
A single instance is created | Multiple instances are created |
Helps to optimize application performances. | This may slow down your application |
Should contain a pure function | Contains an impure function |
Conclusion
- Pure pipes execute only when there is a change in a value or its parameters.
- Pure pipe can be applied to pure function
- Pure pipe help to improve application performance.
- Impure pipe can be used wherever we wanted to run the transfer function every time on change detection.
- Impure pipe may degrade performance.