2

I am trying to filter an array of objects using four fields of a form. All four fields are combinable.

The four fields are: 2 dropdowns with multiple selection and 2 text boxes.

When I click on a button I must filter the data based on the selected fields. This is the method I call when clicking the search button:

filterData(form: NgForm) {
    if (this.gridValueClone) {
      const filterType = form.value.selectedItemsType;
      const filterCompany = form.value.selectedItemsCompany;
      const filterDescription = form.value.description;
      const filterNameFile = form.value.nameFile;
      if (filterType.length > 0 || filterCompany.length > 0 || filterDescription || filterNameFile) {
        let search;
        let arrFilter = [];
        if (filterType.length > 0) {
          arrFilter.push({
            "field": "type",
            "value": filterType
          });
        }
        if (filterCompany.length > 0) {
          arrFilter.push({
            "field": "company",
            "value": filterCompany
          });
        }       
        if (filterDescription) {
          arrFilter.push({
            "field": "description",
            "value": filterDescription
          });
        }
        if (filterNameFile) {
          arrFilter.push({
            "field": "name",
            "value": filterNameFile
          });
        }
        const results = this.gridValueClone.filter(data=> {
          arrFilter.forEach(filter => {
              search = data[filter.field] === filter.value;
          });
          return search;
        });
        if (results) {
          this.reportsGridValue = results;
        } else {
          this.reportsGridValue = [];
        }
      }
    }
  }

As I have it, it works correctly with the filters of the text boxes (Description and File Name), you can select a box or combine them and filter well.

But I don't know how to incorporate the multiple selection filters (Type and Company), below I will put an example of the object that I obtain if I select all the filters by which the search should be done:

arrFilter = [
   {
      "field":"type",
      "value":[
         "Type1",
         "Type2",
         "Type3",
         "Type4"
      ]
   },
   {
      "field":"company",
      "value":[
         "CompanyA",
         "CompanyB"
      ]
   },
   {
      "field":"description",
      "value":"Prueba"
   },
   {
      "field":"name",
      "value":"Prueba.txt"
   }
]

Any suggestion? Thank you.

1 Answer 1

2

Just invoke the correct logic based on whether filter.value is an array or not.

This should work:

const results = this.gridValueClone.filter(data => 
    arrFilter.every(filter =>
        Array.isArray(filter.value)
            ? filter.value.includes(data[filter.field])
            : filter.value === data[filter.field]
    )
);

Your usage of forEach() in the filter callback is a little wonky so I got rid of that and replaced it with a call to every().

Sign up to request clarification or add additional context in comments.

6 Comments

True, I forget to remove a "return", I have already updated it.
Yeah, I saw. Still, forEach() is not the right method for that context. Updated my answer to reflect that.
Great, for it to work ok, I had to add a "{" just after the arrow function and to the Array.isArray block add the "return", thanks
It worked fine for me, but one of the dropdowns doesn't work well, although I'm reviewing it to introduce the pertinent adjustments.
I had a superfluous } leftover in the code, so I removed that. Shouldn't need the code block and return statement.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.