1

I've created a filter-pipe to perform filtering for an array of objects. This pipe gets a filterArgs object which contains some properties on which basis the items should be filtered.

@Pipe({
    name: 'filter'
})
export class FilterPipe implements PipeTransform {
    transform(items: Item[], filterArgs: any): Item[] {
        return items.filter(item => ...);
    }
}

Additionally, I have some input fields where users can set the filter arguments. I bind the properties of the filterArgs object directly and apply the filter for the items like this:

<input type="date" [(ngModel)]="filterArgs.dateFrom">
<input type="date" [(ngModel)]="filterArgs.dateTo">

<ul>
    <li *ngFor="let item of items | filter:filterArgs>...</li>
</ul>

In my component, the filterArgs object is defined as follows (schematic):

public filterArgs: any;

ngOnInit() {
    this.filterArgs = {
        dateFrom = undefined,
        dateTo = undefined
    };
}

So the problem now is, that the filter doesn't get applied when one of the input fields change. As far is I've understood Angular's change detection, this is because the filterArgs object's reference doesn't change and therefore Angular doesn't detect any changes. This is expected behavior and by design.

My question now is: What's the proposed way to resolve this issue?

The naive approach would be to create a new filterArgs object every time an input field changes, so that the reference of this object gets updated. In that case Angular's change detection would kick in. But there must be a better way to do this. I'd image that I could annotate the filterArgs property with some kind of attribute that tells Angular to perform a "deep object compare" for detecting changes.

1 Answer 1

2

For components and directives you can implement DoCheck to perform custom change detection but for pipes this is not supported.

Alternatively you can "optimize" the pipe by using

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

And return cached result when the filter didn't change

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. An impure pipe is not an option for me due to performance reasons. I also don't need change detection for the filtered items themselfs. The custom change detection is only needed for the filterArgs object. I think I'll go with an immutable filterArgs object like stated in this blog post. (i.e. create a new filterArgs object every time an input field gets updated)
I also think that this is the better option for your situation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.