0

I'm trying to build a filter search bar function that filters through a set amount of objects from an API. I keep getting this error "uncaught in promise keyword.toLowerCase() is not a function" error and not sure why. My goal is to start typing in a name and have it filter through the list, but I can't get the list and the search bar to work together.

I have done console.log(listStudents) to try and see what value I should be using, but I'm not sure how to specify the correct value - searching by name - whether first or last - and what would work. I have also tried various specific values, like data.student and data.firstName etc but it doesn't work.

Here is my FilterSearch component:

export default function FilterSearch() {
  const [name, setName] = useState(" ");
  const [foundUsers, setFoundUsers] = useState([]);

  const filter = (keyword) => {
    setName(keyword); 
    if (!keyword || keyword !== " ") {
      setFoundUsers([]); 
    }
    axios.get(USERS).then((listStudents) => {
      console.log(listStudents);
      const results = listStudents.data.students.filter((keyword) => {
        return name.toLowerCase(keyword).startsWith(keyword.toLowerCase());
      });
      setFoundUsers(results);
    });
  };

  return (
    <div className="container">
      <form>
        <input
          type="search"
          value={name}
          onChange={(e) => {
            filter(e.target.value);
          }}
          className="input"
          placeholder="Filter"
        />
        ;
      </form>

      <div className="user-list">
        {foundUsers && foundUsers.length > 0 ? (
          foundUsers.map((name) => <StudentInfo name={name} />)
        ) : (
          <h1>No results found!</h1>
        )}
      </div>
    </div>
  );
}

Can someone help me identify where I can fix this to make the API and the search bar work together?

dlombardi
  • 25
  • 5
  • (1) Your `data.students.filter((keyword) =>` means that your `keyword` identifier is actually a *student object* - figure out the structure of student objects so you can navigate to their names instead. Maybe you need `data.students.filter((student) =>` and then reference `student.name`. (2) `setName(keyword)` doesn't set that name until the next render - keep referring to `keyword` instead (without shadowing it with another unrelated variable when iterating over `students`) – CertainPerformance May 09 '22 at 23:12
  • What is the best way to refine the search when the first and last name are separate entities, i.e. `data.students[0].firstName` and `data.students[0].lastName` but you want to be able to include both as potential search results – dlombardi May 09 '22 at 23:39

0 Answers0