Search code examples
angulartypescriptangular-filtersangular-pipe

angular filter pipe on multiple values of table columns


I'm trying to implement filter pipe on multiple value on multiple attribute in a table.

I'm able to filter multiple value on one attribute. But I'm not able to do it for multiple values of multiple attributes.

My pipe filter implementation for multiple value in a single attribute,

import { Pipe, PipeTransform } from '@angular/core';

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

export class VFilterPipe implements PipeTransform {

  transform(vList: any[], vfilter?: any): any {
    if (!vList|| !Object.keys(vfilter).length) {
      return vList;
    } 
    return vList.filter(item => {
          for (let key in vfilter) {
            for(let value in vfilter[key]){
             if ((item[key] === undefined || item[key] == vfilter[key][value])) 
             {
              return true;
             }
           }
           return false;
         }
         return false;
       });
  }
}

My input array is given ,

vList = [{'name':'jack','age':'25'},{'name':'sam','age':'25'},{'name':'smith','age':'25'},{'name':'jack','age':'28'}]

vfilter = {'name':['jack','sam'],'age':['25']}

I expect the output like the one below after filtering,

vList = [{'name':'jack','age':'25'},{'name':'sam','age':'25'}]

But I'm getting the below result,

vList = [{'name':'jack','age':'25'},{'name':'sam','age':'25'},{'name':'jack','age':'28'}]

can anyone help me on solving this logical problem.


Solution

  • Your code logic bug is that you are returning true if any of the filters match when you want to only return true if all the filters match.

    stackblitz

    transform(vList: any[], vfilter?: any): any {
      if (!vList || !Object.keys(vfilter).length) {
        return vList;
      } 
      return vList.filter(item => {
              return Object.keys(vfilter)
                .filter(_ => vfilter.hasOwnProperty(_))
                .every(key => {
                  if(!item[key]) return true; // matches undefined value
                  const arrayValues = vfilter[key] as any[];
                  return arrayValues.some(_ => _ === item[key]);
              });
          });
    }