Jean D.
Jean D.

Reputation: 169

Optional chaining in combination with toLowerCase and indexOf during array map

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

Answers (2)

tokland
tokland

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

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

You can use `Nullish coalescing operator (??)'

like

str => (str ?? "").toLowerCase().indexOf(value.toLowerCase().trim()) >= 0

Upvotes: 2

Related Questions