I have the below array of objects to filter
companies = [
{
division: "Company 1",
departments: ["Department 1", "Department 2", "Department 3"]
},
{
division: "Company 2",
departments: ["Department 2", "Department 3", "Department 4"]
},
{
division: "Company 3",
departments: ["Department 3", "Department 4", "Department 5"]
}
...
]
I can filter on the division using a value changes subscription on a single form input.
this.myForm.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
tap(val => {
let searchTerm = val.searchString;
this.filteredDivisions = this.companies.filter((company) =>
company.division
.toLowerCase()
.indexOf(searchTerm.toLowerCase()) !== -1)
})
).subscribe()
I have been asked to filter on both the division and the array of departments based on the one input. So if the user types Department 1
then only Company 1 would show, but the user could also type Company 1
in the same input box and then only Company 1 would show then as well.
The user should be able to type either a division or department to filter the array.
So how is it possible to set up the filters to filter both on departments and divisions at the same time, using the same input?
Well you will just need to widen a bit the fields that will be matched against the given string
this.myForm.valueChanges
.pipe(
debounceTime(400),
distinctUntilChanged(),
tap(val => {
let searchTerm = val.searchString.toLowerCase();
this.filteredDivisions = this.companies.filter(company => {
// filter against the 'division' property
const divisionMatch =
company.division.toLowerCase().indexOf(searchTerm) !== -1;
// filter against the 'departments' property
const departmentsMatch = () =>
company.departments.find(
department => department.toLowerCase().indexOf(searchTerm) !== -1,
);
// If divisionMatch is true, no need to check further, return true
return divisionMatch || departmentsMatch();
});
}),
)
.subscribe()
I focus your attention on the fact that the departmentsMatch
is a function, as opposed to a simple value, this allows for lazy evaluation. If the division
matches then the departmentsMatch
will never be invoked.