We utilize pipes to convert currency amounts, strings, dates, and other information to an understandable format for the user. Pipes are basic functions in template expressions used to acknowledge input value and return changed value. Pipes are valuable because you’ll be able to utilize them all through your application by only declaring each pipe once. For instance, you’d utilize a pipe to show a date as November 21, 2021, instead of the crude string format Tue Nov 23, 2021, 17:20:25 GMT+0530 (India Standard Time). Angular has numerous built-in pipes for commonplace information changes, counting changes for internationalization (i18n), which utilize local data to organize information. Here are some common built-in pipes used for data formatting:
LowerCasePipe: Changes content to all lower case.
UpperCasePipe: Changes content to all uppercase.
DatePipe: Formats a date value concurring with local rules.
CurrencyPipe: Changes a number to a currency string, organized according to locale.
PercentPipe: Changes a number to a percentage string, organized according to locale.
DecimalPipe: Changes a number into a string with a decimal point, organized according to locale.
AsyncPipe: Used for unwrapping asynchronous values like observables.
Built-in pipes can take us only so far and can be reasonably constraining when extending out the more complex logic in our apps. Customized pipes can be made to expand the functionality of our applications.
Think of pipes in Angular as similar to methods. A method takes arguments and returns something new and that’s exclusively what pipes do. We may pass in a raw date and be given back a string value that’s pleasantly organized for the user interface. Here, the user interface is key as pipes are ordinarily for changing information between our view and model. So, how do we utilize a pipe? Let’s look at one basic component with a binding of a date stamp:
1 2 3 4
<div> <!-- It’ll render 11/23/21 --> <span>{{ rawDate | date:'M/d/yy' }}</span> </div>
In the above example “rawDate” contains the normal date object value returned by the new Date() and then we pipe that object by using DatePipe providing the format of ‘M/d/yy’. So, it will extract the month, date, and year and return them in the requested format. Now that we have a basic understanding about how we use a built-in pipe, let’s move on further to see how we can use custom pipes for transforming data according to our needs.
The most basic function of a pipe is to transform a single value into a new value. This value can be anything; array, string, object, etc. For an explanation of this, we’ll be changing over numeric file sizes into more human-readable formats, such as “5MB” rather than something like “3154667”. But first let’s begin with the essentials - how we’ll utilize the pipe.
Let’s say a picture was just uploaded through a drag and drop and we are getting data from it. A streamlined file object we will work with:
1
2
3
4
5
6
7
export class FileUploadComponent {
file = {
name: 'image.jpg',
size: 3154667,
type: 'image/jpg'
};
}
Now we’re going to render some information about the file (name and size) in a more pleasant format:
1 2 3 4
<div> <span> {{ file.name }} </span> <span> {{ file.size | fileSizePipe }} </span> </div>
For this, we have to create a pipe. Our pipe name is FileSizePipe. To do this we have to run the following angular command:
ng generate pipe file-size
This will create a skeleton file for our file size pipe with name of fileSize.pipe.ts and add an entry of FileSizePipe in the declarations section of app.module.ts file:
1 2 3 4 5 6 7 8 9 10 11 12
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'fileSizePipe' }) export class FileSizePipe implements PipeTransform { transform(value: any, args: any[]): any { return null; } }
Now, as we do not need any arguments and just want to transform the value on which we apply the pipe, we can remove the args argument part of the transform function. And, to make it easier to understand, we rename the value to size. Now we will write the logic of transforming numeric values into the more readable format of MBs in the body section of the transform function.
1
2
3
4
5
6
//...
export class FileSizePipe implements PipeTransform {
transform(size: number): string {
return (size / (1024 * 1024)) + 'MB';
}
}
Now you can see the difference. The first and second are examples of without and with using pipe respectively:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 3154667 -->
{
{
file.size
}
}
<
!--5 MB -->
{
{
file.size | fileSizePipe
}
}