Angular provides the key feature which is its use of “pipes”. Pipes in Angular are a simple way to transform output in the templates.
They are used to format, filter, sort and transform the data before it is displayed. This article will walk through a comprehensive guide to understanding and using built-in and various custom pipes in Angular.
In this detailed guide you will learn the following topics in detail with examples to easily understand Pipes implementation in your esteemed project:
- Pure vs Impure Pipes, their use-cases with examples
- Various In-Build Angular Pipes
- How to Create a Custome Pipe using NG Generate Command and Include it in App Module
- Various Custom Pipes will be helpful to perform various data transformations very easily.
- How to Pass Single or Multiple Arguments in a Pipe?
- How to Chain Multiple Pipes on a Single Value?
- And Much More…
Let’s Dive in …
What are Pipes in Angular?
Angular provides some handy filters known as Pipes, which make it very easy to format or transform data values according to our needs. Pipes are used with a Pipe (|) character and take an input and return a desired formatted output. Angular provides various built-in Pipes and also we can create our own Pipes.
Pure and Impure Pipes in Angular with Examples
In Angular, Pipes are broadly divided into two types based on the behaviour and how they manipulate the values they take in, process and give out.
Pure Pipes
Pure pipes are the default pipe type in Angular. They only transform values when the input changes. This makes them very efficient because Angular doesn’t have to keep checking for changes if the input hasn’t changed.
For example, Angular’s built-in DatePipe, UpperCasePipe, and LowerCasePipe are all pure pipes. They transform the input into a date string or change the case of a string, but they don’t keep checking for changes if the input date or string hasn’t changed.
Here’s an example of a pure pipe that doubles a number:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'double'
})
export class DoublePipe implements PipeTransform {
transform(value: number): number {
return value * 2;
}
}
You can use this pipe in your template like this:
<p>{{ 5 | double }}</p> <!-- Output: 10 -->
Impure Pipes
Impure pipes, on the other hand, execute every time there’s a change detection cycle, like when a button is clicked or an input value changes. This makes them less efficient, but they’re necessary for tasks like filtering and sorting data, which need to be done every time the data changes.
Here’s an example of an impure pipe that filters an array of numbers:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter',
pure: false
})
export class FilterPipe implements PipeTransform {
transform(value: number[], limit: number): number[] {
return value.filter(num => num < limit);
}
}
You can use this pipe in your template like this:
<p>{{ [1, 2, 3, 4, 5] | filter:3 }}</p> <!-- Output: 1,2 -->
Above pipe filters out numbers that are less than 3. Because it’s an impure pipe, it will execute every time there’s a change detection cycle, not just when the input array changes. This behaviour is required because the limit might change, or the numbers in the array might change, and we want the output to always render the current state of the data.
Using a Pipe
Pipes can be easily used in HTML templates. For instance, let’s consider a scenario where we want to convert a big date object into a readable format. Here’s how you can do it:
lastLoggedInTime = new Date(2018, 5, 25);
Without Pipe:
<div>
Last Logged in @ {{lastLoggedInTime}}
<!-- OUTPUT Last Logged in @ Mon Jun 25 2018 11:48:11 GMT+0530 (India Standard Time) -->
</div>
With date Pipe:
<div>
Last Logged in @ {{lastLoggedInTime | date}}
<!-- OUTPUT Last Logged in @ Jun 25, 2018 -->
</div>
How to Add Parameters in Pipes?
You can add any number of optional parameters or multiple arguments in pipes by adding a (:) character. For instance, the date pipe which we used above can be used as follows:
{{lastLoggedInTime | date:'shortDate' }}
//6/25/18
{{lastLoggedInTime | date:'fullDate' }}
//Monday, June 25, 2018
{{lastLoggedInTime | date:'M/d/yy, h:mm a' }}
//6/25/18, 11:48 AM
Angular Pipe with Multiple Arguments
Here’s how to pass multiple arguments to a pipe. The arguments are separated by colons (:). Here’s an example of a custom pipe that takes multiple arguments:
@Pipe({
name: 'exponentialStrength'
})
export class ExponentialStrengthPipe implements PipeTransform {
transform(value: number, exponent1: string, exponent2: string): number {
let exp1 = parseFloat(exponent1);
let exp2 = parseFloat(exponent2);
return Math.pow(value, isNaN(exp1) ? 1 : exp1) * (isNaN(exp2) ? 1 : exp2);
}
}
You can use this pipe in your template like this:
<p>Super power boost: {{2 | exponentialStrength:'2':'3'}}</p>
Built-in Pipes in Angular with Examples
Angular provides a number of built-in pipes including
- DatePipe
- CurrencyPipe
- AsyncPipe
- DecimalPipe
- JsonPipe
- KeyValuePipe
- LowerCasePipe
- PercentPipe
- SlicePipe
- TitleCasePipe
- UpperCasePipe
Each of these pipes serves a unique purpose and can be used to transform data in different ways.
Let’s have a look at examples of each of the built-in pipes and their various use cases:
Date Pipe in Angular
DatePipe is used for formatting dates. For example, if you have a date object, you can use DatePipe to format it in a user-friendly way.
{{ dateObj | date }} // output is 'Jun 15, 2015'
{{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 AM'
{{ dateObj | date:'shortTime' }} // output is '9:43 AM'
How to Add Timezone in Angular Date Pipe?
The DatePipe can take a timezone as an optional third argument. The timezone is specified as a string in the format ‘+HHmm’ or ‘-HHmm’. If not specified, the local system timezone of the user’s machine will be used.
<p>The time is {{today | date:'shortTime':'GMT+01:00'}}</p>
In this example, the time will be displayed in the GMT+1 timezone.
Currency Pipe
It is used to format a number as currency. It can take the currency code, symbol display option, and digit info as parameters.
{{ price | currency }} // output is '$9.99'
{{ price | currency:'EUR' }} // output is '€9.99'
{{ price | currency:'EUR':'code' }} // output is 'EUR9.99'
AsyncPipe
The AsyncPipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the pipe marks the component to be checked for changes.
{{ observableData | async }} // output is the latest value emitted by `observableData`
Angular Async Pipe Default Value
If you want to display a default value while waiting for the data, you can use the ngIf
directive with the as
keyword:
<div *ngIf="observableData | async as data; else loading">
{{ data }}
</div>
<ng-template #loading>Loading...</ng-template>
In this example, “Loading…” will be displayed until observableData
emits a value.
Decimal or Number Pipe
The Decimal or number pipe is used to transform a number into a string with a decimal point. It can take a string as a parameter to format the number in different ways.
{{ pi | number:'1.0-2' }} // output is '3.14'
Json Pipe
The JSON pipe is used to convert data into JSON format. It is mostly used to for debugging purpose to display all the value in the object
{{ object | json }} // output is a JSON stringified representation of `object`
KeyValue Pipe
The KeyValue Pipe transforms Object or Map into an array of key-value pairs.
<div *ngFor="let item of object | keyvalue">
{{item.key}}:{{item.value}}
</div>
LowerCase Pipe
LowerCase pipe is used to transform text to lowercase.
{{ 'HELLO' | lowercase }} // output is 'hello'
Percent Pipe
The Percent pipe is used to transform a number into a percentage string.
{{ 0.99 | percent }} // output is '99%'
Slice Pipe
The slice pipe creates a new List or String containing a subset (slice) of the elements.
{{ 'hello' | slice:1:3 }} // output is 'el'
TitleCase Pipe
TitleCasePipe is used to transform text to title case.
{{ 'hello world' | titlecase }} // output is 'Hello World'
UpperCasePipe
UpperCasePipe is used to transform text to uppercase.
{{ 'hello' | uppercase }} // output is 'HELLO'
Creating a Custom Pipe
While Angular provides a number of built-in pipes, there may be scenarios where you want to transform values in custom formats. In such cases, you can create your own pipes in Angular. Here’s how you can do it:
First, create a new class which will import the Pipe class and have @Pipe decorator with meta-information name. You can generate a new pipe named ‘foo’ using the following ng command in CLI:
$ ng generate pipe foo
This command will add FooPipe in the app.module.ts file’s declaration array. The foo.pipe.ts file will look like this:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'foo'
})
export class FooPipe implements PipeTransform {
transform(value: any, ...args: any[]): any {
return null;
}
}
You can then modify the transform method to return a modified value:
transform(value: string, footext?: string): string {
return footext+"_"+value+"_"+footext;
}
Now, you can use this Pipe in the template:
{{someFooText | foo:'Freaky' }}
//OUTPUT Freaky_MyFooText_Freaky
Make sure you add the custom pipe into the declarations array in AppModule or any Child Module:
@NgModule({
declarations: [
AppComponent,
CustomPipe //<--Add Custome Pipes here
],
imports: [
BrowserModule
// other imports...
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Various Useful Custom Pipes
Custom pipes in Angular can be created to meet specific needs in web development. Here are some examples:
Text Truncation Pipe
Truncate a string to a specified length and append an ellipsis (…) or any other set of characters to indicate that the text has been shortened.
@Pipe({
name: 'truncate'
})
export class TruncatePipe implements PipeTransform {
transform(value: string, limit = 25, completeWords = false, ellipsis = '...') {
if (completeWords) {
limit = value.substr(0, limit).lastIndexOf(' ');
}
return `${value.substr(0, limit)}${ellipsis}`;
}
}
Search Filter Pipe
Filter an array of objects based on a search term. It can be used to implement search functionality in a list or table view.
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if (!items) return [];
if (!searchText) return items;
searchText = searchText.toLowerCase();
return items.filter( it => {
return it.toLowerCase().includes(searchText);
});
}
}
Sort Pipe
Sort an array of objects based on a specified property. It can be used to implement sorting functionality in a list or table view.
@Pipe({
name: 'sort'
})
export class SortPipe implements PipeTransform {
transform(array: any[], field: string): any[] {
array.sort((a: any, b: any) => {
if (a[field] < b[field]) {
return -1;
} else if (a[field] > b[field]) {
return 1;
} else {
return 0;
}
});
return array;
}
}
Time Ago Pipe
This pipe can be used to convert a timestamp into a “time ago” string (e.g., “2 hours ago”, “3 days ago”).
@Pipe({
name: 'timeAgo'
})
export class TimeAgoPipe implements PipeTransform {
transform(value: any, args?: any): any {
let now = new Date().getTime();
let difference = now - new Date(value).getTime();
return Math.floor(difference / 1000 / 60) + ' minutes ago';
}
}
Time Pipe in Angular
Angular doesn’t have a built-in time pipe, but you can create a custom one. Here’s an example of a custom pipe that formats a Date object into a time string:
@Pipe({
name: 'time'
})
export class TimePipe implements PipeTransform {
transform(value: Date): string {
let hours = value.getHours();
let minutes = value.getMinutes();
return `${hours}:${minutes}`;
}
}
You can use this pipe in your template like this:
<p>The time is {{today | time}}</p>
today
is a Date object representing the current date and time, the output will be the current time.
File Size Pipe
Used to convert a file size from bytes to a more readable format (e.g., KB, MB, GB).
@Pipe({
name: 'fileSize'
})
export class FileSizePipe implements PipeTransform {
transform(size: number): string {
let result;
if (size < 1024) {
result = size + ' bytes';
} else if (size < 1048576) {
result = (size / 1024).toFixed(1) + ' KB';
} else if (size < 1073741824) {
result = (size / 1048576).toFixed(1) + ' MB';
} else {
result = (size / 1073741824).toFixed(1) + ' GB';
}
return result;
}
}
Safe HTML Pipe
This pipe can be used to bypass Angular’s built-in security for binding raw HTML content.
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'safeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
transform(value: any, args?: any): any {
return this.sanitizer.bypassSecurityTrustHtml(value);
}
}
Array Reverse Pipe
Used to reverse the order of items in an array.
@Pipe({
name: 'reverse',
pure: false
})
export class ReversePipe implements PipeTransform {
transform(value) {
return value.slice().reverse();
}
}
CamelCase to Space Pipe:
Convert a camelCase string to a string with spaces (e.g., “camelCase” to “camel Case”).
@Pipe({name: 'camelCaseToSpace'})
export class CamelCaseToSpacePipe implements PipeTransform {
transform(value: string): string {
return value.replace(/([A-Z])/g, ' $1').trim();
}
}
Initials Pipe
This pipe can be used to extract the initials from a full name.
@Pipe({
name: 'initials'
})
export class InitialsPipe implements PipeTransform {
transform(value: string, args?: any): any {
let names = value.split(' '),
initials = names[0].substring(0, 1).toUpperCase();
if (names.length > 1) {
initials += names[names.length - 1].substring(0, 1).toUpperCase();
}
return initials;
}
}
Masking Pipe
This pipe can be used to mask sensitive data like credit card numbers or phone numbers.
@Pipe({
name: 'mask'
})
export class MaskPipe implements PipeTransform {
transform(value: string, visibleDigits: number = 4): string {
let maskedSection = value.slice(0, -visibleDigits);
let visibleSection = value.slice(-visibleDigits);
return maskedSection.replace(/./g, '*') + visibleSection;
}
}
Angular Capitalize Pipe
Angular doesn’t have a built-in capitalize pipe, but you can easily create a custom one:
@Pipe({
name: 'capitalize'
})
export class CapitalizePipe implements PipeTransform {
transform(value: any, args?: any): any {
if (value) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
return value;
}
}
You can use this pipe in your template like this:
<p>{{'hello, how are you?' | capitalize}}</p>
The output will be “Hello, How Are You?”.
Chaining Multiple Pipes
Angular allows you to use multiple pipes on a single value with the chaining of Pipe characters. The pipe character (|) is used for chaining multiple pipes. Here’s how you can do it:
{{someFooText | foo:'Freaky' | foo2 | foo3:'what':'when' }}
Conclusion
Angular pipes are a powerful tool that can greatly enhance functionality and helps in enriching the user experience.
Angular provides a wide variety of built-in pipes with various options to that handle common use cases like date formatting and string manipulation. Also, we discussed how to easily create custom pipes that can be tailored to specific needs.