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
.