skip to Main Content

I have 1 level nested object.

e.g. Teacher and Students. query hold the value entered in search bar. I am trying to filter the array but it does not seem to work. I am missing something basic but cant figure

const studentunderT = [
  {
    id: 1,
    therapist_FName: 'Wonder',
    therapist_LName: 'Women',
    students: [
      { id: 1, student_LName: 'Test', student_Initial: 'BT1' },
      { id: 2, student_LName: 'Test', student_Initial: 'AL' },
    ],
  },
];
{
        studentunderT.filter(post => {
          if (query === '') {
            return post;
        } else if (post.students.some(std=>(
            std.student_Initial.toLowerCase().includes(query.toLowerCase())))) 
        {
          return post;
        }
        }).map((thr) => (
        <>
        {thr.students.map((stu) => (
            <Avatar color="red" key={thr.id} component={Link} to="/complete">{stu.student_Initial}
            </Avatar>
        ))
        }

3

Answers


  1. As mentioned in the comments above, the callback passed to Array.prototype.filter() must return a Boolean value (true to keep, false to discard). Yours potentially returns an object or undefined.

    Sounds like you want something like this…

    const queryResults = useMemo(() => {
      if (query.trim().length === 0) {
        return studentunderT;
      }
      const normalisedQuery = query.trim().toLowerCase();
      return studentunderT.filter(({ students }) =>
        students.some(({ student_Initial }) =>
          student_Initial.toLowerCase().includes(normalisedQuery)
        )
      );
    }, [studentunderT, query]);
    

    then you can use the memo-ised, filtered array in your JSX

    {queryResults.flatMap(({ students }) =>
      students.map((stu) => (
        <Avatar color="red" key={stu.id} component={Link} to="/complete">
          {stu.student_Initial}
        </Avatar>
      ))
    )}
    

    Note I’ve used the student id as the key for your Avatar component; the teacher ID would not have been unique for each student.

    Edit thirsty-hooks-h7e9ps

    Login or Signup to reply.
  2. If you want to filter all the students separately, you can first create a flattened array with Array#flatMap before applying the filter.

    studentunderT.flatMap(x => x.students)
        .filter(s => s.student_Initial.toLowerCase().includes(query.toLowerCase()))
        .map(s => {/* return your JSX for each student */})
    
    Login or Signup to reply.
  3. If you prefer to declare a variable of filteredStudents with a dynamic value and then inside your JSX just map over this filtered-students array.

    NOTE: I used value 'B' for query as you mentioned in your comment.

    const query = 'B';
    const studentunderT = [
      {
        id: 1,
        therapist_FName: 'Wonder',
        therapist_LName: 'Women',
        students: [
          { id: 1, student_LName: 'Test', student_Initial: 'BT1' },
          { id: 2, student_LName: 'Test', student_Initial: 'AL' },
        ],
      },
    ];
    const filteredStudents = studentunderT.map(therapist => {
        if (query === '') {
         return therapist.students;
        }
        else {
         return therapist.students.filter(std => std.student_Initial
          .toLowerCase().includes(query.toLowerCase()));
        }
    })
    console.log('filteredStudents[0]:',filteredStudents[0]);

    And then in your JSX:

    filteredStudents[0].map(stu => (
     <Avatar color="red" key={stu.id} component={Link} to="/complete">{stu.student_Initial}
     </Avatar>
    )
    

    EDIT2:
    As in the discussion bellow in the comments, if you were to have a more complex functionality, such as choosing between therapists, you can do that functionality such as that the [0] value to be dynamic rather than hardcoded:

    filteredStudents[therapistID-1].map(stu => ( //...
    

    NOTE: therapistID would be a state that equals to = therapist‘s id, you then subtract -1 when accessing it, since arrays are 0-based meaning that they start at index 0 and I suspect you to use incrementing id‘s of each therapist.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search