Problem filtering items in a table in real time

0

I have to do a modal within which you have to perform a search and go completing the input that is generated.

The information I look for in an API, here is the code:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends React.Component {
  constructor (props) {
super(props);
this.setState = {
  users: [],
  filteredUsers: []
 };
}


componentDidMount () {
fetch('/users')
  .then((resp) => resp.json())
  .then((users) => {
    this.setState({ users });
  })
  .catch(function(error) {
    console.log(error);
  });
}


 search (e) {
let value = e.target.value;
// hace un filtrado del array de usuarios para obtener
// aquellos cuyo nombre contiene lo ingresado en el input
let filteredUsers = this.state.users.filter((user) => {
  return user.name.includes(value);
});
// actualiza el estado y por ende, la tabla
this.setState({
  filteredUsers
});
}

render() {
return (
  <div className="App">
    <div className="App-header">
      <img src={logo} className="App-logo" alt="logo" />
      <h2>Welcome to React</h2>
    </div>
    <p className="App-intro">
      To get started, edit <code>src/App.js</code> and save to reload.
    </p>

    <button type="button" className="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>


    <div id="myModal" className="modal fade" role="dialog">
      <div className="modal-dialog">


        <div className="modal-content">
          <div className="modal-header">
            <button type="button" className="close" data-dismiss="modal">&times;</button>
            <h4 className="modal-title">Add Note</h4>
          </div>
          <div className="modal-body">
            <h5 className="modal-title">New Note </h5>
            <input 
                type="text" 
                id="myInput" 
                name="search"   
                placeholder="Search.."
                title="Type in a name"
                onChange={this.search.bind(this)}     
            ></input>

          <table>
            <thead>
              <tr>
                <th>Name</th>
                <th>Username</th>
                <th>Email</th>
                <th>Address</th>
                <th>Phone</th>
                <th>Company</th>
                <th>website</th>
              </tr>
            </thead>
            <tbody>
            {
              this.state.filteredUsers.map((user) => (
                <tr>
                  <td>{user.name}</td>
                  <td>{user.username}</td>
                  <td>{user.email}</td>
                  <td>{user.address}</td>
                  <td>{user.phone}</td>
                  <td>{user.company}</td>
                  <td>{user.website}</td>
                </tr>
              ))
            }
            </tbody>
          </table> 

          </div>
          <div className="modal-footer">
            Import: <input type="checkbox" id="myCheck"></input>
            <button type="button" className="btn btn-default" data-dismiss="modal">Add Note</button>
            <button type="button" className="btn btn-default" data-dismiss="modal">cancelar</button>

          </div>
        </div>

      </div>
    </div>

  </div>






     );
 }
}

    export default App;

In theory the code what it does is that look for the data in the API and go auto completing everything.

It works well until I put the body of the table, when I add that block of code I tried to run the program the only thing I get is a blank screen and I do not know why.

At the moment I remove that block of code the program runs perfect.

    
asked by lewa14 05.02.2017 в 18:44
source

2 answers

0
  

Note: The problem is because of me. In your previous question I made this typographical error by posting my answer in a hurry.

The problem is in the constructor:

constructor (props) {
  this.setState = { // incorrecto
    users: [],
    filteredUsers: []
   };
}

When the status is initialized, it is done by assigning directly the values. The setState method is used only to update the status. When there is not an initialized state, the method setState is not reachable (basically, it does not exist in the component). Also, what you have is a typographical error.

constructor (props) {
  this.state = { // correcto
    users: [],
    filteredUsers: []
   };
}

The map , contrary to what they say in the other answer it is correct because an arrow function with a single expression can omit the return . In case you use keys ( {} ), yes you should add the return .

In addition, you can improve the search method a bit more. For example, you can use trim to remove spaces to the ends of the entered text because, if it is not done, when entering a space all the users would be visible . Also, if everything entered is deleted, you must return false and hide all users.

search (e) {
  // hace un filtrado del array de usuarios para obtener
  // aquellos cuyo nombre contiene lo ingresado en el input
  let filteredUsers = this.state.users.filter((user) => {
    let enteredText = e.target.value.toLowerCase().trim();
    let name = user.name.toLowerCase();

    if (!enteredText.length) {
      return false;
    }
    return name.includes(enteredText);
  });

  // actualiza el estado y por ende, la tabla
  this.setState({ filteredUsers });
}

I've done a Pen so you can see the functional example.

    
answered by 06.02.2017 / 17:21
source
-1

The map method goes through all the values of an array and changes what it enters so you return in the return, your method that you use for the map does not have a return, so each element is null, that's not what you will give error or present you nothing in the render.

    
answered by 06.02.2017 в 04:25