0

I have this application where I have 3 search fields: username, organisation and active(boolean). On pressing the search button i am filtering a table by using a combination of the values above or by single search.

My Json:

[
    {
        "id": 1,
        "userName": "abc",
        "active": true,
        "organisations": [{
            "id": 2,
            "organisation": "org1"
        },
        {
            "id": 3,
            "organisation": "org2"
        }]
    },
    {
        "id": 2,
        "userName": "def",
        "active": true,
        "organisations": [{
            "id": 4,
            "organisation": "org4"
        },
        {
            "id": 5,
            "organisation": "org5"
        }]
    },
    {
        "id": 3,
        "userName": "ghj",
        "active": false,
        "lastLogon": "",
        "organisations": [{
            "id": 6,
            "organisation": "org6"
        },
        {
            "id": 7,
            "organisation": "org7"
        }]
    }
]

My Filter:

@Pipe({name: 'searchfilter'})
export class SearchFilterPipe implements PipeTransform {
    transform(items: Array<any>, filter: {[key: string]: any }): Array<any> {
        return items.filter(item => {
                let notMatchingField = Object.keys(filter)
                                             .find(key => item[key] !== filter[key]);

                return !notMatchingField;
            });
    }
}

My Html:

<tr *ngFor="let user of users | searchfilter: tableFilter;">
     <td>{{ user.userName }}</td>
     <td><input type="checkbox" [checked]="user.active"></td>
</tr>

tableFilter is the search object which can either have a single search field or combination of two or three fields. Eg: tableFilter = {"userName":"abc"} or tableFilter = {"userName":"abc", "active": true} or tableFilter = {"userName":"abc", "organisation:"org6", "active": true}.

My code works for username or active or both. But it fails when I use organisation either as a single field or in a combination, as my array is nested.

So any help with the Pipe filter will be helpful. I have heard of the library Lodash but I donno how to use that. Thanks in advance.

Anurag
  • 15
  • 1
  • 6
  • "organisation:"org6" in your tableFilter won't work. You're comparing a string to an array without any logic. You'll need additional logic to look in an array – austinthedeveloper Mar 04 '20 at 17:46
  • It works for other fields. But since organisation is nested, it fails! – Anurag Mar 04 '20 at 17:50
  • Does this answer your question? [Recursively filter array of objects](https://stackoverflow.com/questions/38132146/recursively-filter-array-of-objects) – Aviad P. Jul 19 '21 at 06:54

1 Answers1

0

Can you try below code snipped

 export class SearchFilterPipe implements PipeTransform {
  transform(items: Array<any>, filter: { [key: string]: any }): Array<any> {
    return items.filter(item => {
      return this.findItem(item, filter);
    });
  }

  findItem(currentItem: any, filterItem: any): boolean {
    let keysInFilter = Object.keys(filterItem).find(filterKey => {
      let isItemFound = false;
      if (filterKey === 'organisation') {
        isItemFound = currentItem?.organisations.find((orgItems: any) => orgItems[filterKey] === filterItem[filterKey]) !== null;
      } else {
        isItemFound = currentItem[filterKey] === filterItem[filterKey]
      }

      return isItemFound;
    })

    return Object.keys(filterItem).length === keysInFilter?.length;
  }