MrTheBarintokyo
MrTheBarintokyo

Reputation: 97

How to ignore filtering for fields that are empty/undefined using filterPredicate

I am trying to understand the filterPredicate of MatTableDataSource, and when I thought I was close, I am missing some logic.

I want to filter through a datasource and if the array's value is blank or "", then it shouldn't filter for every value that is defined as "". In other words, filter with what it does know and not what it doesn't know.

I tried to assign the values to null if the length of the array is equal to 0. But even that did not work.

Typescript

this.registeredUserService.GetAllAdverts().subscribe(val => {
          this.dataSource = new MatTableDataSource<Card>(val);
          this.dataSource.paginator = this.paginator;
          this.dataSource.filterPredicate = (myObject: IFilter, filterString: any) => {
            let filterObj: IFilter = JSON.parse(filterString);
            if (!filterObj.provinceName.includes(myObject.provinceName) ||
              !filterObj.vehicleMake.includes(myObject.vehicleMake) ||
              !filterObj.vehicleModel.includes(myObject.vehicleModel) ||
              !filterObj.vehicleYear.includes(myObject.vehicleYear) ||
              !filterObj.vehicleColor.includes(myObject.vehicleColor))
            {
              return false;
            }
            else {
              return true;
            }
          }

    filter()//whenever triggered, it should do the filtering
    {
        this.myFilter.provinceName = this.search.value.provinceSelector;
        this.myFilter.vehicleMake = this.search.value.makeSelector;
        this.myFilter.vehicleModel = this.search.value.modelSelector;
        this.myFilter.vehicleColor = this.search.value.colorSelector;
        this.myFilter.vehicleYear = this.search.value.yearSelector;

        if (this.myFilter.provinceName.length == 0 &&
          this.myFilter.vehicleMake.length == 0 &&
          this.myFilter.vehicleModel.length == 0 &&
          this.myFilter.vehicleColor.length == 0 &&
          this.myFilter.vehicleYear.length == 0) {
          this.dataSource.filter = '';
        }

        else {
          this.dataSource.filter = JSON.stringify(this.myFilter);
        }
      }

    myFilter: IFilter = {
        provinceName: [],
        vehicleMake: [],
        vehicleModel: [],
        vehicleColor: [],
        vehicleYear: []
      }

    interface IFilter{
      provinceName:any[],
      vehicleMake:any[],
      vehicleModel:any[],
      vehicleColor:any[],
      vehicleYear:any[]
    }

What it should do: Filter based on my query

What it does: Only does filtering as soon as all the values are filled.

Upvotes: 0

Views: 1196

Answers (1)

JuNe
JuNe

Reputation: 1997

You just have to check the filter attribute before if it exists and length is greater 0 and when then search for it in your object.

this.registeredUserService.GetAllAdverts().subscribe(val => {
  this.dataSource = new MatTableDataSource<Card>(val);
  this.dataSource.paginator = this.paginator;
  this.dataSource.filterPredicate = (myObject: IFilter, filterString: any) => {
    let filterObj: IFilter = JSON.parse(filterString);
    if (
      (filterObj.provinceName && filterObj.provinceName.length > 0 && !filterObj.provinceName.includes(myObject.provinceName)) ||
      (filterObj.vehicleMake && filterObj.vehicleMake.length > 0 && !filterObj.vehicleMake.includes(myObject.vehicleMake)) ||
      (filterObj.vehicleModel && filterObj.vehicleModel.length > 0 && !filterObj.vehicleModel.includes(myObject.vehicleModel)) ||
      (filterObj.vehicleYear && filterObj.vehicleYear.length > 0 && !filterObj.vehicleYear.includes(myObject.vehicleYear)) ||
      (filterObj.vehicleColor && filterObj.vehicleColor.length > 0 && !filterObj.vehicleColor.includes(myObject.vehicleColor))
     ) {
       return false;
     } else {
       return true;
     }
   }
});

Upvotes: 2

Related Questions