0

I'm trying to filter a jobs list by Job Type, Job Tags (nested array) and job payement. I have a list of checkboxes that contain job types and job tags and two inputs that contain minimum payement and maximum payement

For now, i can only filter the job type with multiple checkboxes value, but i couldn't filter the job tags, neither the payement

I tried this solution here : Filtering array of objects with arrays based on nested value

It didn't work

My job object :

{
    "jobTitle" :"Whatever",
    "jobDescription" : "",
    "jobType" : "EXTRA", // Job Type can be either EXTRA or FULL
    "jobPayement" : 5,   
    "tags" : ["RESTAURANT","EVENT"], //Job Tags are defined with 4 categories RESTAURANT / EVENT / COFFEE / HOTEL
    "xpOnly" : true,
    "image" : "kitchen.png",
   }

My Filter Items (Checkboxes) :

this.filterItems = [
      {
        value: 'Coffee',
        checked: false
      },
      {
        value: 'Event',
        checked: false
      },
      {
        value: 'Hotel',
        checked: false
      },
      {
        value: 'Restaurant',
        checked: false
      },
      {
        value: 'FULL',
        checked: false
      },
      {
        value: 'EXTRA',
        checked: false
      },
    ];

Filter Conditions and ng for

 <a *ngFor="let job of jobs  | fresh: { jobType: ''} : checked();let i = index">

My Filter Pipe :

@Pipe({
  name: 'fresh'
})
export class FreshPipe implements PipeTransform {


  transform(items: any, filter: any, filterItems: Array<any>, isAnd: boolean): any {
    console.log('Filtering ..');
    if (filter && Array.isArray(items) && filterItems) {
      let filterKeys = Object.keys(filter);
      let checkedItems = filterItems.filter(item => { return item.checked; });
      if (!checkedItems || checkedItems.length === 0) { return items; }
      if (isAnd) {
        return items.filter(item =>
            filterKeys.reduce((acc1, keyName) =>
                (acc1 && checkedItems.reduce((acc2, checkedItem) => acc2 && new RegExp(item[keyName], 'gi').test(checkedItem.value) || checkedItem.value === "", true))
              , true)
              );
      } else {
        return items.filter(item => {
          return filterKeys.some((keyName) => {
            return checkedItems.some((checkedItem) => {
              return new RegExp(item[keyName], 'gi').test(checkedItem.value) || checkedItem.value === "";
            });
          });
        });
      } 
    } else {
      return items;
    }
  }


}

checked() {
    return this.filterItems.filter(item => { return item.checked; });
  }

Like i said, for now i got only the filter on Job Type,It would be great if we can find a solution to filter the tags and payement. I'm available for any extra informations Thank you for your help.

Papou SC
  • 21
  • 1
  • 7
  • Worth a read: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe So first, I would recommend to do the logic in your component ts. – AT82 Jul 24 '19 at 16:49
  • It's the first time i use Pipe, i just followed a tutorial. I'll give it a read to understand the logic. Thank you – Papou SC Jul 24 '19 at 18:39

1 Answers1

0

In general is a bad idea use a pipe to filter options. see the posibility of has two variables, "jobs" and "filteredJobs".

for filter by filterItems, it's only create an array with the tags and use "some".

    //create the array with the tags, e.g. ["Event","Restaurant"]
    const filter=this.filterItems.filter(x=>x.checked).map(x=>x.value);

    //use "some"
    this.filteredJobs=this.jobs.filter(job=>
        job.tags.some(t=>filter.indexOf(t)>=0)
    )
Eliseo
  • 50,109
  • 4
  • 29
  • 67