When writing a custom pipe in Angular you can specify whether you define a pure or an impure pipe:

@Pipe({
  name: 'myCustomPipe', 
  pure: false/true        <----- here (default is `true`)
})
export class MyCustomPipe {}

Pure Pipe

  • good for transformation primitive input values like String, Number, Boolean or object reference like Date,
  • bad for the transformation of a complex object
  • it doesn’t detect changes when changing the length of the array
  • executes whenever it detects a change for the input or reference
  • does not work when mutating data in an array

Example

In this example, you can see the student list being filtered through the UniversityPipe:

// App.component.html:

<input placeholder="name" #name>
<input placeholder="university" #university>
<button (click)="add(name.value, university.value)">Add student</button>
<div>  
  <table>    
    <th>Name University</th>    
    <tr *ngFor="let student of (students | university)">
      <td>{{student.name}}</td>
      <td>{{student.university}}</td>   
    </tr>  
  </table>
</div>
// App.component.ts:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
@ViewChild('name') name: ElementRef;
@ViewChild('university') university: ElementRef;
students = [
    { name: 'John', university: 'University of Chicago' },
    { name: 'Ann', university: 'University of Pensylwania' },
    { name: 'Sarah', university: 'University of Pensylwania'},
    { name: 'Mike', university: 'Yale University' },
    { name: 'Kevin', university: 'Yale University'},
    { name: 'Jack', university: 'Yale University' }
  ]
add(name: string, university: string) {
  this.students.push({name, university});
  this.name.nativeElement.value = '';
  this.university.nativeElement.value = '';
}
// UniversityPipe.ts:

import { Pipe, PipeTransform } from '@angular/core';
import { Student } from './student';
@Pipe({
  name: 'university',
})
export class UniversityPipe implements PipeTransform {
  transform(students: Student[]): Student[] {
    return students.filter((student) => student.university ===
'University of Pensylwania');
  }
}

This pipe works if the array length is still the same. If we add a new student to our list, the pipe won’t work.

Impure pipe

  • good for use with complex objects
  • detects changes when the length of an array is changed, such as when added or deleted
  • detects differences in nested objects
  • detects changes with each change, e.g. button clicks
  • slows down the performance of the application

If we add a value ‘false’ to property ‘pure’ we obtain an impure pipe:

@Pipe({
  name: 'university',
  pure: false
})

Now, when we add a new student to the board, our list will update.

Summary

A pure pipe is only called when Angular detects a change in the value or the parameters passed to a pipe.

An impure pipe is called for every change detection cycle no matter whether the value or parameter(s) changes. which leads to bad performance. thats why it is not recommneded to use pipes for filtering data. (their use may slow down the application.)

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *