How to search for anything from an array of objects,?
const [searchInput, setSearchInput] = useState('');
let cars = [
{
"color": "purple",
"type": "minivan",
"registration": new Date('2017-01-03'),
"capacity": 7
},
{
"color": "red",
"type": "station wagon",
"registration": new Date('2018-03-03'),
"capacity": 5
},
]
return (
<>
<input type="text" onChange={(e) =>setSearchInput(e.target.value)}
{
cars?.filter(x => Object.values(x).includes(searchInput.toLowerCase())).map((d) =>{
console.log(d) // nothing is consoled from here tu
//show the data here but nothing is showing here
})
}
</>
)
No errors but the data are not showing whatsoever, what is wrong here?
CodePudding user response:
Object.values(x).includes(searchInput.toLowerCase())
will return Boolean value. thus map will not get executed
change you return statement like below
return (
<>
<input type="text" onChange={(e) => setSearchInput(e.target.value)} />
{
cars?.map((x) => (
Object.values(x).includes(searchInput?.toLowerCase()) &&
<>
//something do here
</>
))
}
</>
)
CodePudding user response:
import React, {useState} from "react";
import "./style.css";
export default function App() {
const [searchInput, setSearchInput] = useState("");
let cars = [
{
"color": "purple",
"type": "minivan",
"registration": new Date('2017-01-03'),
"capacity": 7
},
{
"color": "red",
"type": "station wagon",
"registration": new Date('2018-03-03'),
"capacity": 5
},
];
return (
<div>
<input type="text" onChange={e=> setSearchInput(e.target.value)}/>
{
cars?.filter(x => Object.values(x).includes(searchInput.toLowerCase())).map((d) =>{
console.log(d) // nothing is consoled from here tu
return <span key={d.registration}>{d.color}</span>
})
}
<h1>Hello StackBlitz!</h1>
<p>Start editing to see some magic happen :)</p>
</div>
);
}
CodePudding user response:
Try the function filterCars below your cars array.
const filterCars = cars.filter(car => {
if (!searchInput) {
return cars
}
return car.color.includes(searchInput.toLowerCase()) || car.type.includes(searchInput.toLowerCase())
})
Then your return statement,
return (
<div>
{
filterCars.map(car => (
<p>{car.color}</p>
<p>{car.type}</p>
)}
</div>
)
Note: I excluded your input element because it's fine, and should work.
CodePudding user response:
The OP for the search needs to filter
the cars
array where for every car item
one needs to verify whether the search
value is included in some
of the item's values
.
Also the OP needs to come up with the meaningful custom stringification of every item's value in order to assure a valid search result.
The provided approach implements a single filter function where everything from the above mentioned is included. The filter function is aware of its this
context which is the to be searched value. The latter gets provided as the filter
method's 2nd thisArg
parameter.
Thus a possible solution boils down to ... cars.filter(doesItemContainBoundSearch, search)
... which is proven with the next provided example code.
function stringifySearchTarget(target) {
return (target instanceof Date)
? target.toISOString()
: String(target)
}
function doesItemContainBoundSearch(item) {
const search = this.toLowerCase();
return Object
.values(item)
.some(value =>
stringifySearchTarget(value)
.toLowerCase()
.includes(search)
);
}
let cars = [{
color: "purple",
type: "minivan",
registration: new Date('2017-01-03'),
capacity: 7,
}, {
color: "red",
type: "station wagon",
registration: new Date('2018-03-03'),
capacity: 5,
}];
['o', 'a', 'ur', 'red', 'wagon', 'wagons']
.forEach(search =>
console.log([
JSON.stringify(search),
'=>',
JSON.stringify(
// the next line is everything the OP needs
// in order to filter the `cars` array by
// any item's value which matches the search.
cars.filter(doesItemContainBoundSearch, search)
),
].join(' '))
);
.as-console-wrapper { min-height: 100%!important; top: 0; }