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.
CodePudding user response:
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()
.