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

I am unable to understand impure pipes.

What's the difference between pure and impure pipes?

Please explain with a simple and basic example.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Mr_Perfect
  • 8,254
  • 11
  • 35
  • 62
  • read the [The essential difference between pure and impure pipes and why that matters](https://medium.com/@maximus.koretskyi/the-essential-difference-between-pure-and-impure-pipes-and-why-that-matters-999818aa068) which explains the details behind the difference and explores the underlying mental model – Max Koretskyi Sep 01 '17 at 09:07

5 Answers5

134

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.

This is relevant for changes that are not detected by Angular

  • when you pass an array or object that got the content changed (but is still the same instance)
  • when the pipe injects a service to get access to other values, Angular doesn't recognize if they have changed.

In these cases you probably still want the pipe to be executed.

You should be aware that impure pipes are prone to be inefficient. For example when an array is passed into the pipe to filter, sort, ... then this work might be done every time change detection runs (which is quite often especially with the default ChangeDetectionStrategy setting) event though the array might not even have changed. Your pipe should try to recognize this and for example return cached results.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 3
    Can u pls explain me with an example? – Mr_Perfect Sep 02 '16 at 06:28
  • 2
    Example to demonstrate what exactly? http://stackoverflow.com/a/37828164/217408 shows a filter pipe (but no caching) – Günter Zöchbauer Sep 02 '16 at 06:31
  • Pure pipe means, It will execute every time when someone change the input passed to it. For example, `{{ 2 | exponent: var }}; . Now, when we change the input `var`, then the value is updated. Likewise, please update my value by impure pipe. Anyone?? Here `exponent` is my pipe – Mr_Perfect Sep 02 '16 at 06:45
  • 22
    An impure pipe does the same but its `transform()` method is called much more often. If `xxx` in `{{xxx | filter}}` is an array and an item gets added or removed, then a pure pipe won't be called because Angular doesn't recognize `xxx` as changed because it's the same `xxx` (with a different content though). If you make it `pure: false` then Angular2 doesn't care whether `xxx` has changed or not it calls the `transform()` every time change detection is executed. – Günter Zöchbauer Sep 02 '16 at 06:50
  • 1
    @GünterZöchbauer does an impure pipe differ from binding a function? I'm concerning if their effect on the performance are different or not. – Bünyamin Sarıgül Jun 18 '18 at 08:27
  • @BünyaminSarıgül I don't really understand the question. The difference is, that an impure pipe is evaluated every time change detection is run, while a pure pipe is only evaluated when change detection recognizes a change of the value or one of the parameters passed to the pipe. – Günter Zöchbauer Jun 18 '18 at 08:30
  • 1
    @GünterZöchbauer Sorry for unclear question. I know the difference between pure and impure pipe, I think my question may be a little bit irrelevant of this post. Thus, I posted another question. Please see https://stackoverflow.com/questions/50905721/angular-impure-pipe-vs-function – Bünyamin Sarıgül Jun 18 '18 at 08:51
46

Beside previous answer, I want to add another difference: the number of instances.

Suppose a pipe is used several times in a HTML code. Like:

<p> {{'Hello' | translate }}<p>
<p> {{'World' | translate }}<p>
  • If pipe is pure: there will be only one instance of the pipe. The transform method will be called twice but on the same instance.
  • If pipe is impure: there will be two instances of the pipe.

(you can see this by generating a random id in the constructor of the pipe and print it in both: constructor and transform method)

As pure pipes (or generally pure functions) does(should) not have ANY side effects, the same pure code can be reused any number of times without worries. Seems this is why pure pipes are only once instantiated.

OBS: this is valid in my angular 4.0 environment.

Dacian
  • 678
  • 6
  • 12
  • 1
    In Angular version >= 9 where Ivy is used, even the pure pipes will have multiple instances. For more info refer this article: https://indepth.dev/posts/1447/how-pure-and-impure-pipes-work-in-angular-ivy – Shadab Umer May 11 '22 at 11:45
32

Demo: difference b/w pure and impure pipe

In angular, a pipe can be used as pure and impure

What is pure or impure pipe?

In simple words,
impure-pipe works for every change in the component
pure-pipe works only when the component is loaded.

How to make pipe or impure pure?

@Pipe({
  name: 'sort',
  pure: false //true makes it pure and false makes it impure
})
export class myPipe implements PipeTransform {

  transform(value: any, args?: any): any {
     //your logic here and return the result
  }

}

How to use it?

<div> {{ arrayOfElements | sort }}<div>

Be careful while using impure pipe because this may over-use your system resources in case of inappropriate use.

Read in depth: Pure vs Impure Pipe

WasiF
  • 26,101
  • 16
  • 120
  • 128
  • 3
    great answer i was looking this type of answer with great sample thank you so much – Innocent Oct 07 '18 at 07:01
  • 4
    I doubt on your second point, `pure-pipe works only when the component is loaded`, instead pure pipe works only when there is change in the parameters passed to it not only on component load. for your reference you can check here https://stackblitz.com/edit/pure-impure-pipe – Pardeep Jain Dec 15 '19 at 13:28
  • @PardeepJain You're right but with angular version 8. If see my demo, it is using angular version 6 so angular improved pipe performance in angular version 7 or 8. – WasiF Dec 16 '19 at 13:04
14

Pure & impure Pipes

  • pure pipes are the pipes which are executed only when a "PURE CHANGE" to the input value is detected.

  • A pure change is either a change to a primitive input (string, number etc) value. or changed Object reference.

  • by default a pipe is pure pipe.

  • So impure pipe executes everytime irrespective of source has changed or not. which leads to bad performance. thats why it is not recommneded to use pipes for filtering data.

To make a pipe impure:

@Pipe({
  name: 'empFilter',
  pure: false  // default is set to true.
})
export class EmpFilterPipe implements PipeTransform {

  transform(employees: Employee[], searchValue?: string): Employee[] {
  
   }
}
<input type="text" [(ngModel)]="searchValue">
<button (click)="changeData()"></button>

changeData(): void{
    this.employees[0].name = "SOMETHING ELSE";
}

<div *ngFor="let emp of employees | empFilter : searchValue">
    {{emp.name}}
</div> 

NOTE: if the pipe is pure and employees data is changed using method changeData(), which modifies the property of an employee in the array, the change is not passed to the pipe for transform. The transform will not happen again since the input value to the EmpFilterPipe is the employees array, an object/reference which has not been changed (only its properties have changed), and pure pipes only notice object/reference changes.

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
Ritu Gupta
  • 2,249
  • 1
  • 18
  • 11
5

"Pure pipes":

  1. A pure pipe uses a pure function. It is only called when Angular detects a change in the value or the parameters passed as an input to a pipe. A pure pipe has many advantages over impure pipe:
  2. A pure pipe will revaluate only when there is a change in the value or parameter passed.
  3. A pure pipe will cache the results of the previous value or inputs. So a pure pipe can bind the output from a cache without revaluating if the input doesn't change.
  4. A single instance of the pure pipe is used all over the components.
  5. We just have to test it against known inputs and outputs.
  6. Pure pipes evaluate to pure change in either the input value(String, number, boolean) or in the object reference(Date, Array, Object).
  7. Inputs should not be mutable in case of pure pipes.

"Impure Pipes":

  1. An impure pipe is called on every change detection cycle in Angular. It is called on every digest cycle irrespective of the change in the input or value. If we need some pipe to be called on every change detection, mark the pipe as impure. In the case of impure pipes, Angular will call the transform() method on every change cycle.
  2. Multiple instances are created for impure pipes.
  3. Impure pipes are not re-used.
  4. We can't use cache in case of impure pipes.
  5. Depends on some internal state.
  6. Called at every change detection cycle.
  7. Inputs passed to this pipe can be mutable.

Examples of Impure Pipes

a. Async Pipe

b. JsonPipe and SlicePipe

.ts file

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

// Pipe
@Pipe({
  name: 'filter',
  pure: true    ----> 'Default is true'
})
export class FilterPipe implements PipeTransform {
  transform(users: User[], searchTerm: string): User[] {
    if (!users || !searchTerm) {
      return users;
    }
    return users.filter(user => user.name.toLowerCase()
      .indexOf(searchTerm.toLowerCase()) !== -1);
  }
}

.html file

<input type="text" [(ngModel)]="searchTerm"  placeholder="Enter name" >
<button (click)="changeProperty()">change by Property</button>
<button (click)="changeReference()">change by Reference</button>
<ul>
<li *ngFor="let user of users | filter:searchTerm">{{user.name}}  </li>
</ul>

Prasenjit Mahato
  • 1,174
  • 15
  • 10