I'm currently working on a component that uses the material 2 table to show some data. I need to be able to write custom filter operations (e.g. price > 1) and combine multiple filters. To make that work i wrote a custom filterPredicate:
customFilterPredicate(data: Coin, filters: Predicate[]): boolean {
var operators = {
'>=': function(a, b){
return +a >= +b
},
'<=': function(a, b){
return +a <= +b
}
}
if(filters.length == 0) return true;
let res = false;
for(var i = 0; i < filters.length; i++){
let conditionMet = operators[filters[i].op](data[filters[i].columnName], filters[i].val);
if(conditionMet) {
res = true;
} else {
res = false;
break;
}
}
return res
}
a interface for the predicate type:
export interface Predicate {
field: columnName
op: string;
val: number;
visible: boolean;
}
The customFilterPredicate loops through all the filters the where passed as parameter and returns true if all conditions have been met and false if one or more have not.
Now I use this function to get the data for the table via service, set my dataSource and replace the filterPredicate of the dataSource:
setData(){
return new Promise((resolve, reject) => {
return this.coinService.getCoins()
.subscribe(coins => {
resolve(coins)
})
})
.then((data: Coin[]) => {
this.dataSource = new MatTableDataSource<Coin>(data);
this.dataSource.filterPredicate = this.customPredicate;
})
}
To funny thing is that the filtering works when I use it, but it always throws an error saying that I cant replace the filterPredicate with my custom one, since it expects the filter parameter to be a string.
So my question is, how can I replace this.dataSource.filterPredicate with mine, without rewriting the function in the material 2 package. Is there a way to do this in typescript?
And if anyone has an idea why this works, despite throwing the error, that would be interesting to haha
This is currently not supported but there is an open feature request on Github. It was added to the features list, so it might be worth following.
In the issue, it is suggested to create your own DataSource
with a filter that accepts arrays instead of strings. Have a look at the MatTableDataSource which extends the DataSource class.