I am building a search functionality for fun using react and i have the following data structure:
data.js
export const data = [
{
"id": 1,
"first_name": "James",
"last_name": "Wattson",
"gender": "M",
"age": 43,
"country": "USA",
},
...
List Data
search query result
codes
const App = () => {
const [query, setQuery] = useState("");
const filterKeys = ["first_name", "last_name", "gender", "age", "country"]
const handleOnChange = (event) => {
const filterQuery = data.filter(value => value.first_name.toLowerCase().includes(event.target.value))
setQuery(filterQuery);
}
const tableResults = query.length > 0 ? query : data;
return (
<div className="form">
<div>
<input placeholder="search..." onChange={handleOnChange}/>
</div>
<div>
<Table data={tableResults}/>
</div>
</div>
);
};
export default App
My search functionality work fine but is only limited on the first_name data as input.
How can i possibly update the const filterQuery variable logic using the .some() array method to be able to add filters based on the array filterKeys strings, which are additional keys that i could search for their values.
Goal: being able to search for the values of each keys, including: first_name, last_name, gender, age, country. the codes above can only search for first_name values
something like this
const filterQuery = data.filter(value => filterKeys.some(key => value[key].toLowerCase().includes(event.target.value)));
but this does not seem to be correct... because it crashing on the chrome console tab while typin. the error Uncaught TypeError: value[key].toLowerCase is not a function
CodePudding user response:
If you get this error:
value[key].toLowerCase is not a function
...it means that value[key] is not a string (maybe null or undefined or numeric?). This is the case with the "age" property, as it seems to be numeric. To deal with this situation silently, chain a call to .toString and make all property lookups conditional, using the optional chaining (?.) operator:
value[key]?.toString()?.toLowerCase()?.includes(event.target.value)
CodePudding user response:
Sometimes you get typeof value[key] Number, Number do not have method toLowerCase(), so you need use:
const filterQuery = data.filter(value => filterKeys.some(key => (value[key] "").toLowerCase().includes(event.target.value)));
CodePudding user response:
You handleOnChange function could be like this:
My solution does not use some array method, just another way to get what you want (do not need the filterKeys as well)
const handleOnChange = (event) => {
const term = event.target.value;
const filterQuery = data.filter((record) => {
return (
Object.values(record)
.filter((r) => !Number.isInteger(r))
.filter((r) => r.toLowerCase().includes(term)).length > 0
);
});
setQuery(filterQuery);
};
Object.values(record) will return all the value of record object, after that, you need to use filter to find which record has value contains event.target.value.


