Reputation: 5238
Following this sample I know I can write my own this.dataSource.filterPredicate
. This works fine as long as I search for a string. I want to filter additionally according to a used state
(=myFilterState
).
I try to use the predicate like
this.dataSource.filterPredicate =
(data: MyElement, filter: string) => data.myType.useState === this.myFilterState;
The problem I'm facing is that when I change this.myFilterState
the filter is not reevaluated until I change the string of the filter
. As long as the filter
remains empty the filterPredicate
is not triggered.
Is there a way to trigger it manually - despite the value of filter
?
Upvotes: 2
Views: 1257
Reputation: 51
LeO's answer is very helpful, but be careful when overriding methods of a class. I tried their solution, and it worked for filtering, but my associated paginator with the table would ALWAYS show 0/0 items, even though it would correctly show the desired number of rows.
Tl;dr Add these lines before the return
statement in LeO's answer
if (this.dataSource.paginator) {
this.dataSource._updatePaginator(this.dataSource.filteredData.length);
}
After spending hours trying to figure out why the paginator always displayed 0/0
, I eventually ran across someone with an unrelated problem who had explicitly put
[length]="dataSource.filteredData.length"
in their mat-paginator
html tag. When I inserted this attribute, the display showed the correct values.
I then looked at angular's table-data-source.ts source code for the _filterData
method at it had these lines (lines 325-327):
if (this.paginator) {
this._updatePaginator(this.filteredData.length);
}
I added these lines in the block of code from LeO's answer and got it to work properly without needing the length attribute of the html tag:
if (this.dataSource.paginator) {
this.dataSource._updatePaginator(this.dataSource.filteredData.length);
}
Upvotes: 1
Reputation: 5238
After investigation of the problem I figured out that the filterpredicate
is triggered by the source code only when the filter
has a value. Otherwise it won't be triggered.
Therefore I come up with the solution to overwrite the internal _filterData
with
this.dataSource._filterData = (data: PropertyCompact[]) => {
this.dataSource.filteredData = data.filter(obj => this.dataSource.filterPredicate(obj, this.dataSource.filter));
return this.dataSource.filteredData;
};
and in case of an change one needs to trigger an update
this.dataSource._updateChangeSubscription();
Upvotes: 5