'Filter Function returns undefined
My React app takes a list of employees from an api call. I have a similar function for a departments component that filters out the departments based on the name. When I do the similar thing for the employees, which have properties first_name & last_name. I get the error
TypeError: Cannot read property 'toLowerCase' of undefined
But when I console.log the response, the names come thru no problem.
below is my useEffect hook I use
useEffect(() => {
if (props.data !== undefined) {
const results = props.data.filter(
resp =>
resp.first_name.toLowerCase().includes(filter) +
" " +
resp.last_name.toLowerCase().includes(filter)
);
setFilteredResults(results);
}
}, [filter, props.data]);
I place the filtered results into a state within an array and then map over them to display
Solution 1:[1]
It's kind of hard to tell exactly what you're trying to do with your filter method, but Array.prototype.filter accepts a callback that, when invoked, is coerced to a boolean. If that boolean is true for a given array element, that result is included in the filtered list. If it is false, the result is not included.
Given that you're returning a non-empty string, all of the results will show up; I think this will get you closer to what you're trying to do:
useEffect(() => {
if (props.data !== undefined) {
const results = props.data.filter(
resp =>
(resp.first_name && resp.first_name.toLowerCase().includes(filter))
&&
(resp.last_name && resp.last_name.toLowerCase().includes(filter))
);
setFilteredResults(results);
}
}, [filter, props.data]);
Use a simple value/null check to ensure first_name and last_name aren't undefined on resp before trying to access them.
Solution 2:[2]
I would say that the easiest way to avoid this would be to check first if resp.first_name is not null and then to call toLowerCase function.
Solution 3:[3]
Your filter function should probably look like this, otherwise you're not returning a boolean but a string:
const results = props.data.filter(
resp => (resp.first_name || '').toLowerCase().includes(filter) &&
(resp.last_name || '').toLowerCase().includes(filter)
);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | gabriel.hayes |
| Solution 2 | Milan Toncic |
| Solution 3 |
