Learn Angular 4.0 In 10 Days - Pipes And ViewChild - Day Five

Let us start the Day 5 of Learning Angular 4.0 in 10 Days Series. In the previous articles, we already discussed Directives in Angular 4.0. If you want to read the previous articles of this series, do visit the below link.

When we want to develop an application, we always start the application with a simple basic common task; i.e., retrieve data, transform data and then display the data in front of the user through our user interface. Retrieving data from any type of data source totally depends on data service providers like web services, web APIs etc. So once data has arrived, we can push those raw data values directly to our user interface for viewing to the user. But sometimes, this does not happen exactly in the same manner. For example, in most use cases, users prefer to see a date in a simple format like 15/02/2017 rather than the raw string format Wed Feb 15, 2017, 00:00:00 GMT-0700 (Pacific Daylight Time). So it is clear from the above example, that some value requires editing before getting viewed into the user interface. Also, it can be noticed that the same type of transformation is required by us in many different user interfaces or vice versa. So, in this scenario, we need to think about some style type property which we can be created centrally and applied whenever we require it globally. So for this purpose, Angular 4 introduces Angular Pipes, a definite way to write display – value transformations that we can declare in our HTML.

What are Pipes?

In Angular 4.0, Pipes are classes implementing a single function interface, accepting an input value with an optional parameter array, returning a transformed value.

Transition From Filter to Pipes

In Angular 1.x, we are familiar with the term filter. Filters are a great way of returning a new collection of data or formatting the new. Filters are basically just a function, which take a single value or collection of values as input and returns a new value or collection of values based on the logical responsibilities. In Angular 4.0, pipes are the modernized version of filters. Most of the inbuilt filters of Angular 1.x have been converted as pipes in Angular 4.0 with some new pipes. Pipes are accessed in our templates in the same way that filters were--with the "pipe" character |. Below table shows the comparison of pipes or filters in both Angular 1.x and Angular 4.0.

In Angular 1.x version, filters are very helpful for formatting any type of value as output in our templates. So with Angular 4.0, we get the same feature, but now it is known as Pipes. Below table shows the comparison of pipes or filters in both Angular 1.x and Angular 4.0.

Filter / Pipes AvailableAngular 1.xAngular 4.0
currencyPP
datePP
uppercasePP
lowercasePP
JsonPP
limitToPP
NumberP 
orderByP 
FilterP 
async P
decimal P
percent P

So we can called Pipes as an modernized version of Filters in Angular 1.x.

Why Pipes?

Actually, Pipes do not give any new feature in our template. In Angular 4.0, we can use logic in the templates also. We can also execute or called a function to obtain the desired value in the template. Basically, pipes provide a sophisticated and handsome way to perform the above task within the templates. Basically, pipes make our code clean and structured.

Syntax of Pipes

  1. myValue | myPipe:param1:param2 | mySecondPipe:param1

The pipe expression or syntax starts with the value followed by the symbol pipe (|), then the pipe name. The params for that pipe can be sent separated by colon (:) symbol. The order of execution is from left to right. However, the pipe operator only works in your templates and not in JavaScript code. In JavaScript, the pipe symbol works as a bitwise operator.

Uses of Pipes

  • We can display only some filtered elements from an array.
  • We can modify or format the value.
  • We can use them as a function.
  • We can do all of the above combined.

 

Filters vs Pipes

In Angular 1.x, filters act as helpers, actually very similar to functions where we can pass the input and other parameters and it returns a formatted value. But in Angular 4.0, pipes work as an operator. The basic idea is, we have an input and we can modify the input applying more than one pipe in it. This not only simplifies the nested pipe logic but also gave us a beautiful and clean syntax for our templates. Secondly, in case of async operations (which is newly introduced in angular 4.0, we will later in this chapter), we need to set things manually in case of angular 1.X filters. But pipes are smart enough to handle async operations.

Basic Pipes

Most of the pipes provided by Angular 4.0 will be familiar with us if we already worked in Angular 1.x. Actually, pipes do not provide any new feature in Angular 4.0. In Angular 4.0, we can use logic in the template. Also, we can execute or fire any function within the template to obtain its return value. The pipe syntax starts with the actual input value followed by the pipe (|) symbol and then the pipe name. the parameters of that pipe can be sent separately by the colon (;) symbol. The order of execution of a pipe is right to left. Normally, pipes work within our template and not in JavaScript code.

New Pipes

The decimal and percent pipes are new in Angular 4.0. These take an argument that indicates the digit information which should be used that is how many integer and fraction digits the number should be formatted with. The argument we pass for formatting follows this pattern:

  1. {minIntegerDigits}.{minFractionDigits} -{maxFractionDigits}.  
Sample code of app.component.inbuildpipe.ts
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'inbuild-pipe',  
  6.     templateUrl: 'app.component.inbuildpipe.html'  
  7. })  
  8.   
  9. export class InBuildPipeComponent implements OnInit {  
  10.     private todayDate: Date;  
  11.     private amount: number;  
  12.     private message: string;  
  13.   
  14.     constructor() { }  
  15.   
  16.     ngOnInit(): void {  
  17.         this.todayDate = new Date();  
  18.         this.amount = 100;  
  19.         this.message = "Angular 4.0 is a Component Based Framework";  
  20.     }  
  21.       
  22. }  
Sample code of app.component.inbuildpipe.html
  1. <div>  
  2.     <h1>Demonstrate of Pipe in Angular 4.0</h1>  
  3.   
  4.     <h2>Date Format</h2>  
  5.     Full Date : {{todayDate}}<br />  
  6.     Short Date : {{todayDate | date:'shortDate'}}<br />  
  7.     Medium Date : {{todayDate | date:'mediumDate'}}<br />  
  8.     Full Date : {{todayDate | date:'fullDate'}}<br />  
  9.     Time : {{todayDate | date:'HH:MM'}}<br />  
  10.     Time : {{todayDate | date:'hh:mm:ss a'}}<br />  
  11.     Time : {{todayDate | date:'hh:mm:ss p'}}<br />  
  12.   
  13.     <h2>Number Format</h2>  
  14.     No Formatting : {{amount}}<br />  
  15.     2 Decimal Place : {{amount |number:'2.2-2'}}  
  16.   
  17.     <h2>Currency Format</h2>  
  18.     No Formatting : {{amount}}<br />  
  19.     USD Doller($) : {{amount |currency:'USD':true}}<br />  
  20.     USD Doller : {{amount |currency:'USD':false}}<br />  
  21.     INR() : {{amount |currency:'INR':true}}<br />  
  22.     INR : {{amount |currency:'INR':false}}<br />  
  23.   
  24.     <h2>String Message</h2>  
  25.     Actual Message : {{message}}<br />  
  26.     Lower Case : {{message | lowercase}}<br />  
  27.     Upper Case : {{message | uppercase}}<br />  
  28.   
  29.     <h2> Percentage Pipes</h2>  
  30.     2 Place Formatting : {{amount | percent :'.2'}}<br /><br />   
  31. </div>  
Output

 
The Async Pipe

Angular 4.0 also introduced a special type of pipe called Async Pipe, which basically allows us to bind our templates directly to values that arrive asynchronously. This feature is a great way for working with promises and observables (we will discuss this in the later chapter). This type of pipes accepts a promise or observable as an input value, updating the view with the appropriate value(s) when the promise is resolved or observable emits a new value. This can have a dual impact on reducing component-level code while also providing incredible performance optimization opportunities when utilized correctly. To see how this works, we'll create a simple promise and have it resolve with a string. After a 5 second delay, the value from the resolved promise will be displayed on the screen.

Sample code of app.component.asyncpipes.ts
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'async-pipe',  
  6.     templateUrl: 'app.component.asyncpipe.html'  
  7. })  
  8.   
  9.   
  10. export class AsyncComponent implements OnInit {  
  11.     private message: string;  
  12.   
  13.     promise: Promise<any>;  
  14.   
  15.   
  16.     constructor() {  
  17.         this.promise = new Promise(function (resolve, reject) {  
  18.             setTimeout(function () {  
  19.                 resolve("Hey, I'm from a promise.");  
  20.             }, 5000)  
  21.         });  
  22.     }  
  23.   
  24.     ngOnInit(): void {  
  25.          
  26.     }  
  27.   
  28. }  
Sample code of app.component.asyncpipes.html
  1. <h1>Async Pipes</h1>  
  2. <h2>{{ promise | async}}</h2>   
Output
 
 
 
Custom

Now, we can define custom pipes in Angular 4.0. For configuring custom pipes, we need to used pipes object. For this, we need to define custom pipe with @Pipe decorator and use it by adding a pipes property to the @View decorator with the pipe class name. We use the transform method to do any logic necessary to convert the value that is being passed in as an input value. We can get a hold of the arguments array as the second parameter and pass in as many as we like from the template.

Sample code of app.pipes.propercase.ts
  1. import { Pipe, PipeTransform } from "@angular/core"  
  2.   
  3. @Pipe({  
  4.     name: 'propercase'  
  5. })  
  6.   
  7. export class ProperCasePipe implements PipeTransform {  
  8.     transform(value: string, reverse: boolean): string {  
  9.         if (typeof (value) == 'string') {  
  10.             let intermediate = reverse == false ? value.toUpperCase() : value.toLowerCase();  
  11.             return (reverse == false ? intermediate[0].toLowerCase() :  
  12.                 intermediate[0].toUpperCase()) + intermediate.substr(1);  
  13.         }  
  14.         else {  
  15.             return value;  
  16.         }  
  17.     }  
  18. }   
Sample code of app.component.custompipe.ts
  1. import { Component, OnInit } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'custom-pipe',  
  6.     templateUrl: 'app.component.custompipe.html'  
  7. })  
  8.   
  9. export class CustomPipeComponent implements OnInit {    
  10.     private message: string;  
  11.   
  12.     constructor() { }  
  13.   
  14.     ngOnInit(): void {         
  15.         this.message = "This is a Custom Pipe";  
  16.     }  
  17.       
  18. }  
Sample code of app.component.custompipe.html
  1. <div>  
  2.     <div class="form-horizontal">  
  3.         <h2 class="aligncenter">Custom Pipes - Proper Case</h2><br />  
  4.         <div class="row">  
  5.             <div class="col-xs-12 col-sm-2 col-md-2">  
  6.                 <span>Enter Text</span>  
  7.             </div>  
  8.             <div class="col-xs-12 col-sm-4 col-md-4">  
  9.                 <input type="text" id="txtFName" placeholder="Enter Text" [(ngModel)]="message" />  
  10.             </div>  
  11.         </div>  
  12.         <div class="row">  
  13.             <div class="col-xs-12 col-sm-2 col-md-2">  
  14.                 <span>Result in Proper Case</span>  
  15.             </div>  
  16.             <div class="col-xs-12 col-sm-4 col-md-4">  
  17.                 <span>{{message | propercase}}</span>  
  18.             </div>  
  19.         </div>  
  20.     </div>  
  21. </div>  
Output

 
 
What is ViewChild?

Basically, a ViewChild is one of the new features which was introduced in Angular 4.0 framework. Since Angular 4.0 basically depends on the component architecture, when we try to develop any web page or UI, it is most obvious that that page or UI must be a component which basically contains a number of multiple different types of components within that component. So in simple words, it is basically a parent component – child component based architecture. In this scenario, there are some situations when a parent component needs to interact with the child component. There are multiple ways to achieve this interaction between parent and child component. One the ways is ViewChild decorator. So if we want to get access to a child component, directive or DOM element from a parent component class, then we can use this ViewChild decorator. So when a parent component need to execute or call any method of the child component, it can inject child component as a viewchild within the parent component. ViewChild returns the first element that matches a given component, directive or template reference selector. In cases where you’d want to access multiple children, you’d use ViewChildren instead.

For implementing ViewChild, we need to use @ViewChild decorator in the parent component. The @ViewChild decorator provides access to the class of child component from the parent component. The @ViewChild is a decorator function that takes the name of a component class as its input and finds its selector in the template of the containing component to bind to. @ViewChild can also be passed to a template reference variable.

Now to illustrate this, we will develop a calculator type UI. In this, we will develop two components.

  1. First component i.e. child component which contains the two textbox from taking inputs and four buttons for performing four basic mathematical operations. After completion of the operation, each button will emit its final value to parent component so that parent component can show those values or perform any other operations on the basis of those values.
  2. Now parent component wants to clear the values from both itsown component and also from child component. For clearing the child component value, parent component will access the child component’s clear() by using the @ViewChild decorator.
Sample code of app.component.child.ts
  1. import { Component, OnInit, Output, EventEmitter } from '@angular/core';  
  2.   
  3. @Component({  
  4.     moduleId: module.id,  
  5.     selector: 'child',  
  6.     templateUrl: 'app.component.child.html'  
  7. })  
  8.   
  9. export class ChildComponent implements OnInit {  
  10.     private firstNumber: number = 0;  
  11.     private secondNumber: number = 0;  
  12.     private result: number = 0;  
  13.   
  14.     @Output() private addNumber: EventEmitter<number> = new EventEmitter<number>();  
  15.     @Output() private subtractNumber: EventEmitter<number> = new EventEmitter<number>();  
  16.     @Output() private multiplyNumber: EventEmitter<number> = new EventEmitter<number>();  
  17.     @Output() private divideNumber: EventEmitter<number> = new EventEmitter<number>();  
  18.   
  19.     constructor() { }  
  20.   
  21.     ngOnInit(): void {  
  22.     }  
  23.   
  24.     private add(): void {  
  25.         this.result = this.firstNumber + this.secondNumber;  
  26.         this.addNumber.emit(this.result);  
  27.     }  
  28.   
  29.     private subtract(): void {  
  30.         this.result = this.firstNumber - this.secondNumber;  
  31.         this.subtractNumber.emit(this.result);  
  32.     }  
  33.   
  34.     private multiply(): void {  
  35.         this.result = this.firstNumber * this.secondNumber;  
  36.         this.multiplyNumber.emit(this.result);  
  37.     }  
  38.   
  39.     private divide(): void {  
  40.         this.result = this.firstNumber / this.secondNumber;  
  41.         this.divideNumber.emit(this.result);  
  42.     }  
  43.   
  44.     public clear(): void {  
  45.         this.firstNumber = 0;  
  46.         this.secondNumber = 0;  
  47.         this.result = 0;  
  48.     }  
  49. }  
Sample code of app.component.child.html
  1. <div class="ibox-content">  
  2.     <div class="row">  
  3.         <div class="col-md-4">  
  4.             Enter First Number  
  5.         </div>  
  6.         <div class="col-md-8">  
  7.             <input type="number" [(ngModel)]="firstNumber" />  
  8.         </div>  
  9.     </div>  
  10.     <div class="row">  
  11.         <div class="col-md-4">  
  12.             Enter Second Number  
  13.         </div>  
  14.         <div class="col-md-8">  
  15.             <input type="number"  [(ngModel)]="secondNumber" />  
  16.         </div>  
  17.     </div>  
  18.     <div class="row">  
  19.         <div class="col-md-4">  
  20.         </div>  
  21.         <div class="col-md-8">  
  22.            <input type="button" value="+" (click)="add()" />  
  23.                 
  24.             <input type="button" value="-" (click)="subtract()" />  
  25.                 
  26.             <input type="button" value="X" (click)="multiply()" />  
  27.                 
  28.             <input type="button" value="/" (click)="divide()" />  
  29.         </div>  
  30.     </div>  
  31. </div>  
Sample code of app.component.parent.ts
  1. import { Component, OnInit, ViewChild } from '@angular/core';  
  2. import { ChildComponent } from './app.component.child';  
  3.   
  4. @Component({  
  5.     moduleId: module.id,  
  6.     selector: 'parent',  
  7.     templateUrl: 'app.component.parent.html'  
  8. })  
  9.   
  10. export class ParentComponent implements OnInit {  
  11.     private result: string = '';  
  12.   
  13.     @ViewChild('calculator'private _calculator: ChildComponent;  
  14.   
  15.     constructor() {  
  16.     }  
  17.   
  18.     ngOnInit(): void {  
  19.     }  
  20.   
  21.     private add(value: number): void {  
  22.         this.result = 'Result of Addition ' + value;  
  23.     }  
  24.   
  25.     private subtract(value: number): void {  
  26.         this.result = 'Result of Substraction ' + value;  
  27.     }  
  28.   
  29.     private multiply(value: number): void {  
  30.         this.result = 'Result of Multiply ' + value;  
  31.     }  
  32.   
  33.     private divide(value: number): void {  
  34.         this.result = 'Result of Division ' + value;  
  35.     }  
  36.   
  37.     private reset(): void {  
  38.         this.result = '';  
  39.         this._calculator.clear();  
  40.     }  
  41. }  
Sample code of app.component.parent.html
  1. <div>  
  2.     <h2>Simple Calculator</h2>  
  3.     <div>  
  4.         <child (addNumber)="add($event)" (subtractNumber)="subtract($event)" (multiplyNumber)="multiply($event)"  
  5.                 (divideNumber)="divide($event)" #calculator></child>  
  6.     </div>  
  7.     <h3>Result</h3>  
  8.     <span>{{result}}</span>  
  9.     <br />  
  10.     <br />  
  11.     <input type="button" value="Reset" (click)="reset()" />  
  12. </div>  
Output