2

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?

2
  • A bit budget approach, but if you don't mind finding field identifiers too, you could data.filter(row => JSON.stringify(row).indexOf(filter) > -1) Commented Sep 8, 2020 at 13:16
  • In fact even for a "real" solution I would consider using JSON.stringify(), and then remove "...": parts (the field names) using some regular expression from the result. Commented Sep 8, 2020 at 13:22

2 Answers 2

1

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>

Sign up to request clarification or add additional context in comments.

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.