Adrián Ruiz
Adrián Ruiz

Reputation: 33

Display a list of users from a REST API and filter with React

I'm new here and also new to react js and I'm having trouble solving 1 exercise that asks to display a list of users coming from a REST API and then to be able to filter it.

I have managed to show it but I don't know how to do the filter.

EDIT:

Well Thanx I manage to use filters as you say :D.

But now I want the user to be able to select which columns are shown and which are not.

For this I have created a select from which I plan to remove the filter but I don't really know how to proceed :/

my app

This is how I'm doing the filter, using a text input.

//Query
  const [query, setQuery] = useState("");

  const search = (data) => {
    return data.filter(
      item => item.name.toLowerCase().includes(query));
  }

the select

<select className='select' onChange={changeFilter}>
        <option value="">All</option>
        <option value="name">Name</option>
        <option value="username">Username</option>
        <option value="email">Email</option>
        <option value="phone">Phone</option>
      </select>

So basically I pretend to change the "name" here: item.name.toLowerCase().includes(query)); for filter and if All is selected its shows all.

Any help with this?

Code from the fetch:

// users from API.
  const [users, setUsers] = useState([]);
  useEffect(() => {
    fetchData();
  }, []);






  // async function
  const fetchData = async () => {
    await fetch('https://jsonplaceholder.typicode.com/users')
      .then(response => response.json())
      .then(data => setUsers(data))
      .catch((error) => {
        console.log("ERROR:" + error);
      })
  }

I modified the way I call the component in App.js

  <div className="App">
      <h1>PRUEBA DE NIVEL</h1>

      <select className='select' onChange={changeSelectedFilter}>
        <option value="">All</option>
        <option value="name">Name</option>
        <option value="username">Username</option>
        <option value="email">Email</option>
        <option value="phone">Phone</option>
      </select>

      <input type="text"
        placeholder='Search...'
        className='search'
        onChange={e => setQuery(e.target.value.toLowerCase())}
      />
      <UserTable data={search(users)} filter={selectedFilter} />

    </div>

Upvotes: 3

Views: 1983

Answers (3)

Amirhossein
Amirhossein

Reputation: 2037

You can use the filter method like this:

const isUserEligible = (user) => {
  if(/* the condition that the user must have */) {
    return true;
  } else {
    return false;
  }
}
users.filter((user) => isUserEligible(user)).map((user) => (
  <UsersList
    key={user.id}
    name={user.name}
    username={user.username}
    email={user.email}
    phone={user.phone}
  />
))

Update:

I didn't understand your question completely. But if you want to show only the selected column in the select box, you can define a state for your select like this:

const [selectedColumn, setSelectedColumn] = useState("");
const changeSelectedColumn = (event) => {
  setSelectedColumn(event.target.value);
}
<select className='select' onChange={changeSelectedColumn}>
  <option value="">All</option>
  <option value="name">Name</option>
  <option value="username">Username</option>
  <option value="email">Email</option>
  <option value="phone">Phone</option>
</select>

And then you can pass the selectedColumn to your UsersList component like this:

users.map((user) => (
  <UsersList
    key={user.id}
    name={user.name}
    username={user.username}
    email={user.email}
    phone={user.phone}
    selectedColumn={selectedColumn}
  />
))

And finally in your UsersList component, show only the selected column by 'if, else' base on the value of the selectedColumn or show all if the selectedColumn value is "". (Means that the user selected All columns).

If you also want to filter by the query, you can use the filter method again as I said before.

Upvotes: 2

Youssouf Oumar
Youssouf Oumar

Reputation: 45963

You could use a state called filterInput for example and an input, and filter(). Like so:

const [users, setUsers] = useState([]);
const [filterInput, setFilterInput] = useState("");
<div>
  <input type="text" value={filterInput} onChange={() => setFilterInput(e.target.value)} />
  {users
    .filter((user) => user.name.includes(filterInput) || user.username.includes(filterInput))
    .map((user) => (
      <UsersList
        key={user.id}
        name={user.name}
        username={user.username}
        email={user.email}
        phone={user.phone}
      />
    ))}
</div>

Upvotes: 1

Anurag Bhagsain
Anurag Bhagsain

Reputation: 423

.filter MDN

users.filter(user => user.name.startsWith('R')).map((user) => (
    <UsersList
      key={user.id}
      name={user.name}
      username={user.username}
      email={user.email}
      phone={user.phone}
    />
  ));

Upvotes: 0

Related Questions