0

I'm trying to sort table data according to one of my key value pairs as defined in the state.

Here is what my state looks like:

class Employee extends Component {
state = {
  employeeData: [],
  filteredEmployeeData: [],
  search: '',
  sort: 'asc',
  error: '',
}

And here is the function I'm trying to use to sort. This is what isn't working for me, I keep getting the error, "Uncaught TypeError: Cannot read property 'state' of undefined"

  sortFirstName(){
    console.log('SORTING!!!!')
    const {employeeData} = this.state
    const sorted = employeeData.sort((a, b) => {
          if (a.name.first < b.name.first){
            return -1
        } else if (a.name.first > b.name.first){
            return 1
        } else {
          return 0
        }
    })
    console.log('Sorted List: ', sorted)
    this.setState({filteredEmployeeData: sorted})
}

And here is how it's populating

render () {
    return (
      <div>
        <Container style={{ minHeight: "80%" }}>
        <br/>
          <h1 className="text-center">Search For An Employee</h1>
          <Alert
            type="danger"
            style={{ opacity: this.state.error ? 1 : 0, marginBottom: 10 }}
          >
            {this.state.error}
          </Alert>
          <SearchForm
            handleInputChange={this.handleInputChange}
            search={this.state.search}
          />
        </Container>
        <Container>
        <table className="table table-hover">
        <thead>
            <tr>
            <th scope="col" >Image</th>
            <th scope="col" value="firstName" onClick={(this.sortFirstName)}>First Name</th>
            <th scope="col" value="lastName">Last Lame</th>
            <th scope="col" value="email">Email</th>
            <th scope="col" value="phoneNumber">Phone Number</th>
            <th scope="col" value="city">City</th>
            <th scope="col" value="SSN">SSN</th>
            </tr>
        </thead>
        <tbody>
        {this.state.filteredEmployeeData.map(ee => (
          <EmployeeData
            id={ee.login.uuid}
            key={ee.login.uuid}
            img={ee.picture.thumbnail}
            firstName={ee.name.first}
            lastName={ee.name.last}
            email={ee.email}
            phone={ee.cell}
            city={ee.location.city}
            ssn={ee.id.value}
          />
        ))}
        </tbody>
        </table>
        </Container>
      </div>
    );
  }}

Separately I have an API call pulling in the employee data on mount and setting both employeeData and filteredEmployeeData as an array of objects. I don't think you need to see that part to get it, but I can share that too if it's helpful.

Any help would be appreciated.

Valborg
  • 95
  • 2
  • 10
  • For component methods in class components you either need to bind the method in the constructor or use an arrow function when defining it. Otherwise it doesn't know what `this` is: https://stackoverflow.com/questions/33973648/react-this-is-undefined-inside-a-component-function – Jayce444 Feb 11 '21 at 01:55

2 Answers2

2

define your sortFirstName as an arrow function, which will bind this correctly to your Employee class:

  sortFirstName = () => {
    console.log('SORTING!!!!')
    const {employeeData} = this.state
    const sorted = employeeData.sort((a, b) => {
          if (a.name.first < b.name.first){
            return -1
        } else if (a.name.first > b.name.first){
            return 1
        } else {
          return 0
        }
    })
    console.log('Sorted List: ', sorted)
    this.setState({filteredEmployeeData: sorted})
}
buzatto
  • 9,704
  • 5
  • 24
  • 33
0

There are two ways you can fix this error.

  1. to bind this in constructor function

    constructor(props) {
       super(props);
       this.state = {
         employeeData: [],
         filteredEmployeeData: [],
         search: '',
         sort: 'asc',
         error: ''
       }
       this.sortFirstName = this.sortFirstName.bind(this);
     }
    

or 2. use arrow function

sortFirstName = () => {
Praveen Nambiar
  • 4,852
  • 1
  • 22
  • 31