Hani Salehi
Hani Salehi

Reputation: 99

How to add a search bar to a react app that filter data from an api?

I am working on a project however i need to add an input where a user can filter the list of students by their name (both first and last name), I have gotten the data from the api the issue is figuring out how to filter the data as I am fairly new to react. Some help would be appreciated. Below is what I have so far.

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import StudentData from './student_data/StudentData'
import './App.css';


function App() {
  const [students, setStudents] = useState(null);
  const studentdata = 'https://www.hatchways.io/api/assessment/students';

  function getStudents(){
    fetch(studentdata)
      .then(resp => resp.json())
      .then(data => {
        setStudents(data);
      })
  }


  return (
    <div className="App">
      <h1>Students</h1>

      <div>
        <button className="fetch-button" onClick={getStudents}>
          Get Students
        </button>
        <br />
      </div>

      <div className="search" id="search">
          <input type="text" ></input>
      </div>

      {students && students.students.map((student, index) => {
       var total = 0;
       for(var i = 0; i < student.grades.length; i++) {
        var grade = parseInt(student.grades[i]);
        total += grade;
       }
       const avg = total / student.grades.length;
       const average = avg.toString();


      return(
      <div className="student" key={index}>
        <div className="image">
          <img src={student.pic} id="icon"></img>
        </div>

        <div className="text">
          <h3 id="name">{student.firstName} {student.lastName}</h3>
          <p id="detail"><strong>EMAIL:</strong> {student.email}</p>
          <p id="detail"><strong>COMPANY:</strong> {student.company}</p>
          <p id="detail"><strong>SKILL:</strong> {student.skill}</p>
          <p id="detail"><strong>AVERAGE:</strong>: {average}%</p>
        </div>
      </div>

      )}
      )}
    </div>
  );
}

export default App;

Upvotes: 0

Views: 659

Answers (1)

RKM
RKM

Reputation: 144

Modified the code little bit and check this helps with the filter.

import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [students, setStudents] = useState(null);
  const [filterData, setFilterData ] = useState(null);

  const studentdata = 'https://www.hatchways.io/api/assessment/students';

  function getStudents(){
    fetch(studentdata)
      .then(resp => resp.json())
      .then(data => {
        setFilterData(data.students);
        setStudents(data.students);
      })
  }

  const searchByName = (event) => {
    event.persist();
    // Get the search term
    const searchItem = event.target.value.trim();
    // If search term is empty fill with full students data
    if(!searchItem.trim()) {
      setFilterData(students);
    }
    // Search the name and if it found retun the same array
    const serachIn = (firstName, lastName) => {
      if(firstName.indexOf(searchItem) !== -1 || lastName.indexOf(searchItem) !== -1) {
        return true;
      }
      let fullName = firstName+" "+lastName;
      if(fullName.indexOf(searchItem) !== -1) {
        return true;
      }
      return false;
    };
    // Filter the array 
    const filteredData = students.filter((item) => {
      return serachIn(item.firstName, item.lastName);
    });
    // Set the state with filtered data
    setFilterData(filteredData);
  }

   return (
    <div className="App">
      <h1>Students</h1>

      <div>
        <button className="fetch-button" onClick={getStudents}>
          Get Students
        </button>
        <br />
      </div>

      <div className="search" id="search">
          <input type="text" name="serachByName" onChange={(e) => searchByName(e)} ></input>
      </div>

      {filterData && filterData.map((student, index) => {
       var total = 0;
       for(var i = 0; i < student.grades.length; i++) {
        var grade = parseInt(student.grades[i]);
        total += grade;
       }
       const avg = total / student.grades.length;
       const average = avg.toString();


      return(
      <div className="student" key={index}>
        <div className="image">
          <img src={student.pic} id="icon"></img>
        </div>

        <div className="text">
          <h3 id="name">{student.firstName} {student.lastName}</h3>
          <p id="detail"><strong>EMAIL:</strong> {student.email}</p>
          <p id="detail"><strong>COMPANY:</strong> {student.company}</p>
          <p id="detail"><strong>SKILL:</strong> {student.skill}</p>
          <p id="detail"><strong>AVERAGE:</strong>: {average}%</p>
        </div>
      </div>

      )}
      )}
    </div>
  );
}

Upvotes: 1

Related Questions