Saturday, October 21, 2023

Custom Pipe in Angular

*Pipe class created by developer towards the requirement of an app is called "custom pipe"

*Custom pipe creation requires "Pipe decorator" and Pipe Transform interface

*Any pipe is a class, which implements PipeTranform interface and provides functionality to transform method


*syntax:
   @Pipe({
      name:'..',
      pure:true|false
        })
  export class <pipeclassname> implements PipeTransform
  {
    transform(value:..,args:..):..
    {
     ->1st para value will receive data to be transformed into required format
     ->2nd para args will receive an option[s],it is an optional
    }
  }

   pinfo.name|lowercase               
                |                                     
              transform                           
              (value,args)                       
                {..}                               

value is nothing but name
lowercase is the pipeclassName 

pinfo.aprice|currency:"INR":"symbol"
                |                                                                          
              (value,args)                        
                {..}                              
value is aprice
args is INR, Symbol



Let us understand the need of Angular Custom Pipe with an example.
Suppose,

.TS Changes

import { Component } from '@angular/core';

@Component({
  selector: 'app-ngpipesdemo',
  templateUrl: './ngpipesdemo.component.html',
  styleUrls: ['./ngpipesdemo.component.css']
})
export class NgpipesdemoComponent {
  Employee: any[] = [
    {
        ID: 'EMP1', Name: 'RaJAKonda UDAY',
        DOB: '12/8/1988', Gender: 'Male', Salary: 12300084.56
    },
    {
        ID: 'EMP2', Name: 'ANURAG Mohanty',
        DOB: '10/14/1989', Gender: 'Male', Salary: 6666.00
    },
    {
        ID: 'EMP3', Name: 'KitTU',
        DOB: '7/24/1992', Gender: 'Male', Salary: 6543.15
    },
    {
        ID: 'EMP4', Name: 'ADcd',
        DOB: '8/19/1990', Gender: 'Female', Salary: 9000.50
    },
    {
        ID: 'EMP5', Name: 'SamBIt SataPATHY',
        DOB: '4/12/1991', Gender: 'Male', Salary: 9876.54
    }
];
}


.html Changes

<table border="1">
    <thead>
        <tr>
            <th>Emp ID</th>
            <th>Name</th>
            <th>DOB</th>
            <th>Gender</th>
            <th>CourseFee</th>            
        </tr>
    </thead>
    <tbody>
        <tr *ngFor='let emp of Employee'>
            <td>{{emp.ID | uppercase}}</td>
            <td>{{emp.Name | titlecase}}</td>
            <td>{{emp.DOB | date:'dd/MM/yyyy'}}</td>
            <td>{{emp.Gender | lowercase}}</td>
            <td>{{emp.Salary | currency:'USD':true}}</td>
        </tr>
    </tbody>
</table>


When we run the above code, without custom pipe we will get the below output











As you can here we have applied some built-in pipes to format the data.

Now, the requirement changes, now they want to show the title depending on the gender of the student I.e. we need to add Mr. or Miss. prefixed before the name.

Only solution is custom Pipe

Creating Angular Custom Pipe using Angular CLI:
ng g pipe custompipe --flat







custompipe.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'custompipe'
})
export class CustompipePipe implements PipeTransform {

  transform(name: string, gender: string): string {
    if (gender.toLowerCase() == "male")
        return "Mr. " + name;
    else
        return "Miss. " + name;
  }
}


Understanding above code:
  1. First, we import the Pipe decorator and PipeTransform interface from the Angular core Library.
  2. Then we decorated the “CustompipePipe” class with the Pipe decorator so that this class will become an Angular pipe.
  3. We then set the name property of the pipe decorator to custompipe so that we can use this name (Custompipe) on any HTML page where we want this pipe functionality.
  4. The CustompipePipe class implements the PipeTransform interface and that interface has one method called transform() and here we implement that method.
  5. As you can see in the above code, the transform method takes 2 parameters (name and gender). The name parameter will receive the name of the employee whereas the gender parameter will receive the gender of the employee. The method returns a string i.e. Mr. or Miss. prefixed to the name of the employee depending on their gender.
We need to register the custom pipe in appModule.ts


















Make changes to html as shown below





















Output












2 Requirement is 

 project
     |
  component1--> dom|date:"EEE MMMM dd/MM/y hh24:mm:ss a"

  component2--> dop|date:"EEE MMMM dd/MM/y hh24:mm:ss a"
    ...                   |
              repetition of date format across component
                          |
             this will not be easy to maintain in the real time
                          |
             the solution is customdate pipe creation


Example

Create a custom pipe first

ng g p customdate --flat










.ts changes

import { Component } from '@angular/core';

@Component({
  selector: 'app-ngpipesdemo',
  templateUrl: './ngpipesdemo.component.html',
  styleUrls: ['./ngpipesdemo.component.css']
})
export class NgpipesdemoComponent {
    pinfo={"name":"dEll",
    "desc":"dell i5 proc with 16gb ram",
    "aprice":50000.55347,
    "oprice":25000.76655,
    "dom":new Date()};
}

.html

<div style="font-size:x-large">
    name: {{pinfo.name|lowercase}} - {{pinfo.name|uppercase}} <br>
    desc: {{pinfo.desc|titlecase}} <br>
   price: {{pinfo.aprice|currency:"INR":"symbol"}} <br>
  oprice: {{pinfo.oprice|number:"1.2-2"}} <br>
    disc  : {{(pinfo.oprice/pinfo.aprice)|percent}} <br>
   dom  : {{pinfo.dom|customdate|lowercase}}
</div>

customdatepipe.ts

import { DatePipe } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'customdate'
})
export class CustomdatePipe extends DatePipe implements PipeTransform {
  override transform(value: Date|string|number): string|null;
  override transform(value: null|undefined): null;
  override transform(value: Date|string|number|null|undefined): string|null;
  override transform(value: Date|string|number|null|undefined): string|null {
      return super.transform(value,"EEE MMM dd/MM/y hh:mm:ss a");
  }
}


OutPut











Note:
-----
Whenever date format need to be changed, developer can change format with
in customdate.pipe.ts
      ...
return super.transform(value,"EEEE MMMM dd/MM/y hh:mm:ss a");
                                   |
                        this change will be reflected accross different components

*pure-true|false [default is true]
   
      true[pure pipe]--single instance of pipe class created for different usages
                       is called "pure pipe"
                       eg: lowercasepipe,uppercasepipe,..

    false[impure pipe]--unique instance of pipe class created to each usage is
                        called "impure pipe"
                        eg: asyncpipe 

*pure pipe provides better performance over impure pipe

No comments:

Post a Comment

Thank you for visiting my blog

Kubernetes

Prerequisites We assume anyone who wants to understand Kubernetes should have an understating of how the Docker works, how the Docker images...