Angular 2 - SPLessons
SPLessons 5 Steps, 3 Clicks
5 Steps - 3 Clicks

Angular 2 Pipes

Angular 2 Pipes

shape Introduction

With Angular's data binding, displaying data is easy by simply binding an element property to a class property. But, not always. Sometimes the data is not in a format appropriate for display. That's where pipes come in handy. Following are the major concepts covered in the chapter.
  • Pipes
  • Custom Pipes

Pipes

shape Description

Pipes transform bound properties before they are displayed so one can alter the property values to make them more user friendly or more local appropriate. Angular provides some built-in pipes for formatting values such as date, number, decimal, percent, currency, uppercase, lowercase, and so on. Angular also provides a few pipes for working with objects such as the JSON pipe to display the content of an object as a JSON string, which is helpful when debugging, and a slice pipe which selects a specific subset of elements from a list. One can also build the own custom pipes in Angular. The syntax below explains the simple example for pipes, suppose if one want to display the product code in lowercase just add the pipe character after the property in the template expression and then specify the lowercase pipe as shown below. Now the product code will transform into lowercase before it is displayed. One can also use pipes in property bindings as shown below. Add the pipe after the property in the template expression and specify the desired pipe, in the above code, pipe added after the property and specified as uppercase pipe so that the image title will appear in all caps. As per the need one can chain the pipes as shown below. From the above example, the price is transformed into a currency. By default, the currency pipe adds the all caps three-letter abbreviation of the local currency to the amount, if one want to display the abbreviation in lowercase, transform it again by simply adding another pipe. Some pipes support parameters, the parameters are defined by specifying a colon and the parameter value as shown below. A currency pipe has three parameters, the desired currency code like ‘USD’, ‘INR’. A Boolean value which indicate whether to display the currency symbol and the digit info, the digit info consist of the minimum number of integer digits, the minimum number of fractional digits and the maximum number of fractional digits. From the above code the value 1.2-2 means at least one digit to the left of the decimal and at least two digits to the right of the decimal and no more than two digits to the right of the decimal, effectively defining two decimal places.

shape Example

In the demo project product management open the product list component template and add a lower case pipe for the product code and currency pipe for the price as shown in the below code. product-list.component.html [html] <div class='panel panel-primary'> <div class='panel-heading'> {{pageTitle} } </div> <div class='panel-body'> <div class='row'> <div class='col-md-2'>Filter by:</div> <div class='col-md-4'> <input type='text' [(ngModel)]='listFilter' /> </div> </div> <div class ='row'> <div class='col-md-6'> <h3>Filtered by: {{listFilter}} </h3> </div> </div> <div class='table-responsive'> <table class='table' *ngIf='products && products.length'> <thead> <tr> <th> <button class='btn btn-success' (click)='toggleImage()'> {{showImage ? 'Hide' : 'Show'} } Image </button> </th> <th>Product</th> <th>Code</th> <th>Available</th> <th>Price</th> <th>5 Star Rating</th> </tr> </thead> <tbody> <tr *ngFor='let product of products'> <td> <img *ngIf='showImage' [src]='product.imageUrl' ='product.productName' [style.width.px]='imageWidth' [style.margin.px]='imageMargin'> </td> <td>{{ product.productName } }</td> <td>{{ product.productCode | lowercase } }</td> <td>{{ product.releaseDate } }</td> <td>{{ product.price | currency:'USD':true:'1.2-2'} }</td> <td>{{ product.starRating } }</td> </tr> </tbody> </table> </div> </div> [/html] In the above code, for the product code the pipe character is simply inserted after the property in the template expression and type lowercase. For price, a pipe chapter and currency are inserted along with few parameters like USD true to display the dollar sign instead of the currency abbreviation and 1.2-2 to specify that at least one number to the left of the decimal place and two and only two numbers to the right of the decimal place.

shape Output

Check the output in the browser, the product code get displayed in lowercase and the price is displayed nicely as a currency as shown in the image below.

Custom pipes

shape Description

The figure below explain the code required to build a custom pipe. First define a class and implement a PipeTransform interface, which has one method, transform. Write code in the transform method to transform a value and return it. The first parameter of the transform method is the value for transforming. In this example, an array of products is transformed into a filtered array of products. Notice that the Iproduct interface is used to strongly type the array that's passed in. The second parameter is for any arguments and need to perform the transformation. In this case, one want to pass in the filter criteria entered by the user. The method return type is also defined as an array of products, because the filtered array of products are returned. Add a pipe decorator to the class to define it as a pipe. Similar to the other decorators used, this is a function so add parentheses. Pass an object to the function specifying the name of the pipe. This is the name for the pipe used in the template. And of course, there are imports to import what one need.

shape Example

In the demo project product management create a new file and name it as product-filter.pipe.ts, and use the below code. product-filter.pipe.ts [c] import { PipeTransform, Pipe } from '@angular/core'; import { IProduct } from './product'; @Pipe({ name: 'productFilter' }) export class ProductFilterPipe implements PipeTransform{ transform(value: IProduct[], filterBy: string): IProduct[] { filterBy = filterBy ? filterBy.toLocaleLowerCase() : null; return filterBy ? value.filter((product: IProduct) => product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value; } } [/c] In the above code, export keyword is used to import the pipe where ever needed and the class with the name product filter pipe defined and pipe transform interface is implemented. The Pipe transform interface is imported from Angular core in the first line of the code. The method is defined for the pipe transform interface using the keyword transform, inside the method the value parameter is defined to be an array of Iproduct and is been imported as shown in the second line of the code. The class is decorated using the pipe decorator and the pipe name is specified as productFilter and the pipe is added to the import statement in the first line of the code. The transform method is implemented using the JavaScript code, the goal is to transform the passed list of products to a filtered list based on a user-entered filter string. This first line of code uses a JavaScript conditional operator to handle the possibility that no filterBy string was defined. If there is a filterBy, this code converts it to lowercase. So one can compare apples to apples when filter the product list. A case insensitive comparison is needed. If there is no filterBy, this code sets the filterBy to null. Then return the filtered list of products. This code also uses the JavaScript conditional operator. If the filter variable has a true value, meaning that it is defined and not null, then the list is filterd. Otherwise, there was no filter specified and one can return the original value, which is the full list of products. Look closer at this filter statement. The array filter method is used to create a new array with elements that pass the test defined in the provided function. Use the ES 2015 arrow syntax to define that filter function. For each product in the list, the product name is converted to lowercase and the IndexOf is used to determine if the filtered text is found in the product name. If so, the element is added to the filtered list. Now use the pipe in the product list component template. In the ngfor class, add the pipe character and the name of the pipe, productFilter. Be sure to insert within the quotes and also pass in the pipe argument. In this example, the listfilter property is passed. That property contains the value the user entered in the filterBy input box. The code below explain using the created pipe. product-list.component.html [html] <div class='panel panel-primary'> <div class='panel-heading'> {{pageTitle}} </div> <div class='panel-body'> <div class='row'> <div class='col-md-2'>Filter by:</div> <div class='col-md-4'> <input type='text' [(ngModel)]='listFilter' /> </div> </div> <div class ='row'> <div class='col-md-6'> <h3>Filtered by: {{listFilter}} </h3> </div> </div> <div class='table-responsive'> <table class='table' *ngIf='products && products.length'> <thead> <tr> <th> <button class='btn btn-success' (click)='toggleImage()'> {{showImage ? 'Hide' : 'Show'}} Image </button> </th> <th>Product</th> <th>Code</th> <th>Available</th> <th>Price</th> <th>5 Star Rating</th> </tr> </thead> <tbody> <tr *ngFor='let product of products | productFilter:listFilter'> <td> <img *ngIf='showImage' [src]='product.imageUrl' ='product.productName' [style.width.px]='imageWidth' [style.margin.px]='imageMargin'> </td> <td>{{ product.productName }}</td> <td>{{ product.productCode | lowercase }}</td> <td>{{ product.releaseDate }}</td> <td>{{ product.price | currency:'USD':true:'1.2-2'}}</td> <td>{{ product.starRating }}</td> </tr> </tbody> </table> </div> </div> [/html] Now, one need to tell the angular about the newly created pipe which can be done by declaring the pipe in an Angular module, open the Angular module which declare the product list component which is the app module in this example. Add ProductFilterPipe in the declaration array an import the ProductFilterPipe as shown in the code below. app.module.ts [c] import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { ProductListComponent } from './products/product-list.component'; import { ProductFilterPipe } from './products/product-filter.pipe'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, ProductListComponent, ProductFilterPipe ], bootstrap: [ AppComponent ] }) export class AppModule { } [/c]

shape Output

Check the output in the browser, the default filter is angular and one can only see the list related to angular as shown in the image below. Now, change the default filter text by using the input box the list only related to the word typed get displayed as indicated in the image below.

Summary

shape Key Points

  • Pipe allows users to take data and format it on the screen, maybe for dates or numbers or other values.
  • A pipe takes in data as input and transforms it to a desired output.
  • One can also build own custom pipes in angular 2