I have a custom pipe to filter an array. The pipe is used inside a child component, data to child component is passed through input parameter. When the input data is changed, pipe is not called. Is there anything I have to do differently when using ChangeDetectionStrategy.OnPush inside child component.
Edit
In the example below, product-list-container gets products from ngrx store. The data is passed into product-list component through input parameter.
In product-list component, i have a filter that is for filtering out rows based on some criteria. The issue I am seeing is that, when input value changes pipe function is not called. Pipe is getting called only once on component load.
@Component({
selector: 'product-list-container',
template: `
<app-product-list [productList]="productList$ | async"></app-product-list>
`
})
export default class ProductListContainer implements OnInit {
public productList$: Observable<Product[]>;
constructor(public store: Store<AppState>) {
}
ngOnInit() {
this.productList$ = this.store.select('productList');
}
}
@Component({
selector: 'app-product-list',
template: `
<div *ngFor="let product of productList | filterActiveProduct">
// More code here
</div>
`,
changeDetection: changeDetectionStrategy.onPush
})
export default class ProductList {
@Input() productList: Product[];
constructor() {
}
}
@Pipe({
name: 'fromNow'
})
export class filterActiveProduct {
transform(products: Product[], args: Array<any>): string {
return products.findAll(p => p.isActive);
}
}
Thanks,
that because your pipe is Pure pipes.
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.
using Impure pipes in your case:
Angular executes an impure pipe during every component change detection cycle. An impure pipe will be called a lot, as often as every keystroke or mouse-move.
With that concern in mind, we must implement an impure pipe with great care. An expensive, long-running pipe could destroy the user experience.
FilterActiveProduct:
@Pipe({
name: 'filterActiveProduct',
pure: false
})
export class FilterActiveProduct {}
ProductList:
@Component({
selector: 'app-product-list',
template: `
<div *ngFor="let product of productList | filterActiveProduct">
// More code here
</div>
`,
})
export default class ProductList {
@Input() productList: Product[];
constructor() {
}
}
Following this document page: https://angular.io/docs/ts/latest/guide/pipes.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With