Reputation: 169
For a autocomplete input I search in project properties during typing. Now I want to improve this code
filterProjects(value: string) {
return this.projects.filter(
project =>
project.key.toLowerCase().indexOf(value.toLowerCase().trim()) >=
0 ||
project.name.toLowerCase().indexOf(value.toLowerCase().trim()) >=
0 ||
project.description?.toLowerCase().indexOf(value.toLowerCase().trim()) >=
0
);
}
with this:
filterProjects(value: string) {
return this.projects.filter(project =>
[project.key, project.name, project.description].map(
str => str?.toLowerCase().indexOf(value.toLowerCase().trim()) >= 0
)
);
}
I use the optional chaining because description
can be null or undefined.
But it doesn't work, meaning the function always returns the array unmodified. Also, when the value is found in the description of one item, the array doesn't get filtered to only this item.
What could be the solution except using "old" checks like if (str !== undefined)
and such?
Upvotes: 3
Views: 1406
Reputation: 67850
That map
returns an array of booleans, which is always truthy no matter what, so it's not the predicate you are looking for. You need Array.some (also in lodash/underscore/ramda, if you plan to target old browsers). Let me tweak also the inner predicate a little bit:
filterProjects(value: string) {
return this.projects.filter(project =>
[project.key, project.name, project.description].some(str =>
str ? str.toLowerCase().includes(value.toLowerCase().trim()) : false
)
);
}
Upvotes: 4
Reputation: 11001
You can use `Nullish coalescing operator (??)'
like
str => (str ?? "").toLowerCase().indexOf(value.toLowerCase().trim()) >= 0
Upvotes: 2