I have a search field which filters through an array when I'm typing. So far it works ok, but I cannot search within the "courses" array! How can I achieve this? The complete array looks like this:
const data = [{
name: "john doe",
city: "blabla",
zipcode: "1234",
email: "[email protected]",
phone: "12345678",
courses: [
{
title: "some course",
provider: "some provider",
end_date: "some date"
},
{
title: "another course",
provider: "another provider",
end_date: "another date"
},
]
]
Here is my JS code so far, where I can search through all fields, except the "courses"-array:
data = data.filter(row => {
return Object.keys(row).some(key => {
return (
String(row[key])
.toLowerCase()
.indexOf(filter) > -1
);
});
});
Can someone help me out?
asked Sep 8, 2020 at 13:03
ST80
3,94319 gold badges73 silver badges150 bronze badges
2 Answers 2
The following will search both, all fields of your top level objects in dataas well as all fields in the objects of each course array:
const data = [{
name: "john doe",
city: "blabla",
zipcode: "1234",
email: "[email protected]",
phone: "12345678",
courses: [
{
title: "some course",
provider: "some provider",
end_date: "some date"
},
{
title: "another course",
provider: "another provider",
end_date: "another date"
},
]},
{
name: "jane aire",
city: "dooodaaah",
zipcode: "987",
email: "[email protected]",
phone: "8997652",
courses: [
{
title: "how to win",
provider: "by herself",
end_date: "tomorrow"
},
{
title: "you can do it",
provider: "Harry",
end_date: "next week"
},
]}
];
// check whether `filter` is found in `value`:
function chk(filter){return function(value){return String(value).toLowerCase().indexOf(filter)>-1}}
const res=document.getElementById('res'); // show found results in <pre id="res">
// whenever the input changes:
document.querySelector('input').oninput=ev=>{
let chkfilt=chk(ev.target.value || null);
res.innerHTML=JSON.stringify(
data.filter(row => { return Object.values(row).some(chkfilt)
|| row.courses.some(o=>Object.values(o).some(chkfilt)) })
,null,2);
}
.as-console-wrapper {max-height:100% !important}
<input type="text" placeholder="search string ...">
<pre id="res"></pre>
answered Sep 8, 2020 at 13:36
Carsten Massmann
28.4k3 gold badges25 silver badges49 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
Below snippet could help you
const data = [
{
name: "john doe",
city: "blabla",
zipcode: "1234",
email: "[email protected]",
phone: "12345678",
courses: [
{
title: "some course",
provider: "some provider",
end_date: "some date",
},
{
title: "another course",
provider: "another provider",
end_date: "another date",
},
],
},
]
const courseTitle = "another"
const res = data.filter(
(el) =>
el.courses.find((course) =>
course.title.toLowerCase().includes(courseTitle.toLowerCase())
) !== undefined
)
console.log(res)
answered Sep 8, 2020 at 13:27
hgb123
14.9k3 gold badges24 silver badges43 bronze badges
Comments
lang-js
data.filter(row => JSON.stringify(row).indexOf(filter) > -1)JSON.stringify(), and then remove"...":parts (the field names) using some regular expression from the result.