1

I am on an Ionic2 / Angular2 project. There I have a

*ngFor="let item of items | async | customPipe"

in my code. The async is because items is an Observable<Item[]>. My customPipe is working fine on the first run. But when I make any change to one if the items that would filter it out through my customPipe it is still shown.

What's the problem? Is the *ngFor only run once? Or do I have to force a DOM-update? Thanks for any help.

Ranjith Varatharajan
  • 1,596
  • 1
  • 33
  • 76
SoS
  • 774
  • 1
  • 7
  • 19
  • 2
    Ok, I just found this: http://stackoverflow.com/questions/34456430/ngfor-doesnt-update-data-with-pipe-in-angular2 I'll give it a try... after I read it .. – SoS Dec 16 '16 at 13:10

2 Answers2

2

According to Angular2 pipe docs:

Angular executes a pure pipe only when it detects a pure change to the input value. A pure change is either a change to a primitive input value (String, Number, Boolean, Symbol) or a changed object reference (Date, Array, Function, Object).

Angular ignores changes within (composite) objects. It won't call a pure pipe if we change an input month, add to an input array, or update an input object property.

Reason:

This may seem restrictive but is is also fast. An object reference check is fast — much faster than a deep check for differences — so Angular can quickly determine if it can skip both the pipe execution and a view update.

So while you change your array or the elements inside the array, the arrays reference doesn't change.

So switching to .onPush or triggering the change detection manually might solve your problem.

Source: https://angular.io/docs/ts/latest/guide/pipes.html#!#pure-and-impure-pipes

Community
  • 1
  • 1
eko
  • 39,722
  • 10
  • 72
  • 98
  • Thanks for the link. I changed my pipe now to `pure: false` and it is working now as expected. Can you please tell me more details about the `.onPush`? What does it and where to put it? Thanks – SoS Dec 16 '16 at 13:29
  • @SoS you just put a `changeDetection: ChangeDetectionStrategy.OnPush` inside your `@Component` annotation. It tells angular to treat any input as if they're immutable. There're more detailed info on the web of course if you're interested. – eko Dec 16 '16 at 13:33
  • using changeDetection:ChangeDetectionStrategy.OnPush and manually triggering ChangeDetectorRef detectChanges() not work for me – teejay Apr 12 '17 at 12:19
  • @teejay can you reproduce it on a plunker? – eko Apr 12 '17 at 12:30
0

Old question but I also stumbled upon the problem of triggering a pure pipe when the array changes.

To let the pure pipe know, that the array changes, we need to pass a new reference of the array. So in the case of items you can try it like this:

this.items = changedItems.slice();
Chimitsu Nagase
  • 167
  • 1
  • 9