Pipes in Angular

angular pipes

This article on Pipes in Angular is part of the Learning Angular series.

Introduction and Why Pipes are Useful

Pipes are used to transform the output.
For a case where one has a name as a string ‘Max’ and wants to output all in uppercase without making it uppercase throughotut the application.
It would be better to modify the value just on display. For that one can use a builtin pipe ‘uppercase’
Using it is simple

{{ username | uppercase }}

This would transform the username in whatever case to uppercase just for displaying and without affecting the original value
As the job of a pipe is to just visually transformt he output, the best place for them to be used is the HTML code.

Using Pipes

Pipe to display dates ‘date’

Parameterizing Pipes

There are also ways to pass parameters to pipes.
This can be done using a colon after the pipe name and pass the parameter afetr that.

date:'fullDate'

One should also make sure that the pipe is able to handle the parameter. In the case of the date pipe, it expects a string parameter.
Additional parameters can also be passed using multiple colons.

pipename:param1:param2...

Where to Learn More About Pipes

All the build-in pipes can be fopuind the PAI documentation in the official Angular.io website.

Chaining Multiple Pipes

Multiple pipes can be chained together by using the pipes one after another seprated by the evrtical bar

{{ server.date | date:'fullDate' | uppercase }}

One thing to keep in mind is the sequence of placing the pipes as the execution happens from eft to right.
The first pipe will be applied to the expression and then the second pipe would be applied to the result of the applciation of the first pipe and continued.
This behavior can be confirmed by applying the uppercase pipe to the date objhect directly which will throw an error becasue it wouldn’t be able to apply the uppercase pipe over ad ate as the uppercase can only be apllied on a string.

Creating a Custom Pipe

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
    name: 'shorten' // this is name that is to be used to use the pipe
})
export class ShortenPipe implements PipeTransform {
    transform(value: string) {
        if (value.length > 10) {
            return value.substr(0, 10) + '...';
        }
        return value;
    }
}

Before using this pipe, it needs to be added to the declatations array in the AppModule.

Parameterizing a Custom Pipe

transform(value: string, limit: number, anotherArg: any) {
...
}

This can be used as

{{ server.name | shorten:15:'..' }}

Example: Creating a Filter Pipe

ng generate pipe filter
This would generate filter.pipe.ts
To add a filter string, add an input area to the template

<input type="text" />

Add the filteredStatus variable to the TS file

Pipe({
    name: 'filter'
})
export class FilterPipe implements PipeTransform {
    transform(value: any, filterString: string, propName: string) {
        if (value.length === 0 || filterString === '') {
            return value;
        }
        let resultArray = [];
        for (const item of value) {
            if (item[propName) === filterString) {
                resultArray.push(item);
            }
        }
        return resultArray;
    }
}

Can be used as

<ul>
     <li>...</li>
</ul>

Pure and Impure Pipes (or How to Fix the Filter Pipe)

If we use the filter pipe on a list of items and then there are additions/deletions on the list, then the filter doesn’t update the list. This is because this would cause the pipe to rerun on the data for every change in data. This would cause performance issues. If this is a requiredment of utmost importance, this behaviour can be achieved by using the pure tag in the Pipe declaration

Pipe({
    name: 'filter',
    pure: false
})
export class FilterPipe implements PipeTransform {
    ...
}

Understanding the async Pipe

In some cases, we need to wait for the data to return before we could output it.
For a typical case like a Promise,

appStatus = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('live');
        ), 2000);
    });

In this case, if we directly output the appStatus in string interpolation, the output string will show as [object Object]. This is right as because the Promise is an Object type, but when the Promise returns the string, the string interpolation has no way to know that the data type has changed. To make sure that the string interpolation knows that something has changed, the ‘async’ pipe can be used.

{{ appStatus | async }}

This way when the data gets updated after the promise resolves, the paragraph shows the output.
The async can be used with Promise and Observables.

Leave a Reply