Open In App

Explain pure and impure pipe in Angular

Last Updated : 28 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will learn about Pure and Impure pipes in Angular. We will also explore how Angular handles both types of pipes with an example.

What are Angular Pipes?

Angular Pipes are a way to transform the format of output data for display. The data can be strings, currency amounts, dates, etc. Pipes are simple functions that accept an input and return a transformed value in a more technical understanding. They do not alter the data but change into the required format to display in the browser. Angular provides many built-in pipes for typical data transformation. You can also create custom pipes if you want to do custom transformation.

Angular Pipes

Angular Pipes

Angular Pipes

Features:

  • Pipes are defined using the pipe “|” symbol.
  • We can apply two formats to single data by chaining pipes. A chained pipe is when the output of the first pipe is input to the next pipe.
  • Pipes can have optional parameters using the colon(:) symbol to fine-tune the output.

Example: We will use a built-in pipe uppercase that transforms text to all upper cases.

Javascript




import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  template: `{{ title | uppercase}}`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'pipes in angular';
}


Output:

 

Pure and Impure Pipes: In Angular, Pipes are of two types.

  • Pure Pipes
  • Impure Pipes

Pure Pipes:

  • Pure pipes in angular are the pipes that execute when it detects a pure change in the input value.
  • A pure change is when the change detection cycle detects a change to either a primitive input value (such as String, Number, Boolean, or Symbol) or object reference (such as Date, Array, Function, or Object). Let’s see an example,

HTML




<div> {{ user | myPipe }} </div>


Javascript




import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  user = { name:'Rohit', age: 23};
}


here, user is an object and myPipe is a custom Pipe. 
  • myPipe will execute if it detects a change in the user’s object reference.
  • What will happen if I try to change the property of users? Will the myPipe executes?

Javascript




user.age = 19;


  • The answer is no. myPipe will not execute even if the property has changed because the object reference is still the same. To detect this change, Angular will have to do a deep check for differences within the object. Also, this change is not pure; the pipe ignores the changes within objects.
  • A single instance of pipe is used all over the component.
  • A pure must use a pure function.
  • A pure function does not depend on any state, data, or change during the execution. In other words, given the same arguments, a pure function should always return the same output.

Javascript




function add(a, b){
    return a + b
 }


  • In the above example, If the argument values are not changed, the function will return the same output. So it does not depend on state change.
  • By default, pipes in angular are pure pipes. Custom pipes can be defined as pure pipes by turning the pure flag to true of the @Pipe decorator.

Javascript




@Pipe({
  name: 'purePipe',
  pure: true      
})
export class PurePipe {}


Impure Pipes:

  • Impure pipes in angular are the pipes that execute when it detects an impure change in the input value. 
  • An impure change is when the change detection cycle detects a change to composite objects, such as adding an element to the existing array. Let’s take the same example that we took earlier.

HTML




<div> {{ user | myPipe }} </div>


Javascript




import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  user = { name:'Rohit', age: 23};
}


Javascript




user.age = 19;


  • For the above example, if we want our custom pipe to detect changes within our user object then we have to make the pure attribute to false.

Javascript




@Pipe({
  name: 'myPipe',
  pure: false      
})
export class MyPipe {...}


  • Now, myPipe will execute on every change.
  • Impure pipes are required because angular ignores changes to composite objects.
  • Impure pipes execute every time angular detects any changes regardless of the change in the input value.
  • It uses the impure function.
  • An impure function depends on any state, data, or change during the execution and may not return the same result if the same inputs are passed into the respective function. Let’s take a simple function as an example

Javascript




var discount = 15
 
function calculateAmount(price){
    return total + (price - discount);
}


  • The above function does not return the same output every time. Because the function return value depends on the external variable called discount. It may vary based upon the value. 
  • Multiple instances are created for impure pipes.
  • Async pipe is an example of an Impure pipe.

How Angular Handles Pure and Impure Pipes: The following diagram describes how angular handles Pure and Impure pipes.

How pure and impure pipes are handled by angular

How pure and impure pipes are handled by angular

Pure and Impure Pipes Example: In this example, we will create an Angular app to display employees’ data. We will create a custom pipe to understand the working of pure and impure pipes. The button “Add Employee” is used to add an employee to the list and “Reset” is used to clear the textbox.

 

Custom pipe (search.pipe.ts)

Javascript




import { Pipe, PipeTransform } from '@angular/core';
 
@Pipe({
  name: 'search'
})
export class SearchPipe implements PipeTransform {
 
  transform(value: any, name: string) {
    if(name === ''){
      return value;
    }
    return value.filter((employee) => {
    employee.firstName.startsWith(name)
   });
  }
}


search pipe is used to filter the list based on the text added in the input box.

Component class (app.component.ts)

Javascript




import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  nameString = '';
  employees = [{
      firstName: 'Rohit',
      lastName: 'Sharma',
      dept: 'Finance',
      salary: 5000,
      doj: new Date('2012-04-22')
    },
    {
      firstName: 'Aditi',
      lastName: 'Mishra',
      dept: 'Sales',
      salary: 6000,
      doj: new Date('2016-09-16')
    },
    {
      firstName: 'Dipti',
      lastName: 'Singh',
      dept: 'IT',
      salary: 10000,
      doj: new Date('2021-09-03')
    }
  ]
 
  addUser(){
    this.employees.push({
      firstName: 'Rahul',
      lastName: 'Yadav',
      dept: 'HR',
      salary: 8000,
      doj: new Date('2016-11-19')
    })
  }
 
  reset(){
    this.employees = this.employees.slice()
  }
}


In the component class, there is an array employees 
for storing employees data. The function addUser() 
is used to add employees in the list.

Template (app.component.html)

HTML




<div class="container">
  <h1>Employee Details</h1>
  <span>Search </span>
  <input type="text" [(ngModel)]="nameString">
  <br/><br/>
  <table class="table table-sm table-striped m-t-4">
    <thead class="thead-dark">
      <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Department</th>
      <th>Salary</th>
      <th>Joining Date</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let employee of employees | search:nameString">
      <td>{{employee.firstName}}</td>
      <td>{{employee.lastName}}</td>
      <td>{{employee.dept}}</td>
      <td>{{employee.salary | currency}}</td>
      <td>{{employee.doj | date:'dd/MM/yyyy'}}</td>
    </tr>
  </tbody>
  </table>
  <button type="button" class="btn btn-success m-3"
          (click)="addUser()">
    Add Employee
  </button>
  <button type="button" class="btn btn-success"
          (click)="reset()">
    Reset
  </button>
</div>


Output: The output below shows the working search pipe in the Angular app.

 

Now, let’s explore the pure and impure pipe working in our app. Now we will try to add an employee while we are filtering the data. By default, custom pipes are pure pipes. Therefore, the below output is an example of a pure pipe. 

 

Here, We try to add an employee having the first name with the same starting letter to check if it 
appears in the filtered data.

The filtered list doesn’t update on clicking the Add Employee button because pure pipe ignores changes within objects. The filtered list is updated by clicking the Reset button because it changes the array reference. 

If we use impure pipes, the change will be reflected by just clicking the Add Employee button. Impure pipes now detect change within objects. Let’s see how it is implemented.

Javascript




import { Pipe, PipeTransform } from '@angular/core';
 
@Pipe({
  name: 'search',
  pure: false
})
export class SearchPipe implements PipeTransform {
 
  transform(value: any, name: string) {
    if(name === ''){
      return value;
    }
    return value.filter((employee) => {
    employee.firstName.startsWith(name)
   });
  }
 
}


 

Difference between Pure and Impure pipes

Pure pipe

Impure pipe

The pipe is executed only when it detects a change in primitive value or object reference The pipe is executed on every change detection cycle irrespective of the change in the input value.
A single instance is created. Multiple instances are created
It uses pure function It uses an impure function
Pure pipe optimizes application performances. Impure pipe may slow down your application

Conclusion:

  • Pure pipes detect changes only when there is a change to primitive types or object reference. 
  • Pure pipes optimize the angular change detection cycle because checking primitive values or object references is much faster than detecting a change within an object. 
  • Impure pipes execute every time the change detection runs regardless of input value has changed or not. So, now the code runs on every mouse or keyboard event; this may overuse system resources. If the pipe is heavy, it will degrade the application’s performance.
  • Therefore, Be careful while using impure pipes.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads