0

I have added a function getAttendance which should only be triggered if I click on a table row. If i define

<tr onclick={this.getAttendance} key={key}> It is working fine but if i change it to call my function to <tr onclick={this.getAttendance} key={key}> OR <tr onclick={()=>{this.getAttendance}} key={key}> Its throwing the above error .

import React, { Component } from 'react';
import './Attendance.css';
import { Link, withRouter } from 'react-router-dom';

//@ Redux
import { connect } from 'react-redux';
import propTypes from 'prop-types';
import { get_all_employees} from '../../../../store/actions/employeeActions';

export class Attendance extends Component {
    constructor(props){
        super(props);
    }

    componentDidMount(){
        this.props.get_all_employees();
    }

    getAttendance = (e) => {
        e.preventDefault();
        console.log('Hello');
    }

  render() {
    const tbodylist = [];
    let i = 1;
    const { allemployee } = this.props.employee;
    Object.keys(allemployee).forEach(function(key) {
        console.log(key, allemployee[key]);
        let designation = (allemployee[key].designation === 'M')? 'Manager' : (allemployee[key].designation === 'AM') ? 'Assistant Manager' : (allemployee[key].designation === 'LAS') ? 'LAS' : null ;
        let val =    ( <tr onclick={this.getAttendance}   key={key}>
                        <th scope="row" className='text-uppercase vasp_th'>{i}</th>
                        <td  className='text-uppercase vasp_td'>{allemployee[key].employee_id}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].name}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].doj}</td>
                        <td className='text-uppercase vasp_td'>{designation}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].reporting_name}</td>
                    </tr>);
            tbodylist.push(val);
            i++;
    });

    return (
      <div className='container-fluid'>
        <div className='row'>
            <div className='col-lg'>
            {/**First Row */}
                <div className='row vasp_first_row'>
                    <div className='col-sm'>
                        <button className='btn btn-light bg-white px-4'>Filters</button>
                    </div>
                    <div className='col-sm-3'>
                        <Link className='links' to='/add-sales-person'><button className='btn btn_modified text-uppercase'><i className="fa fa-plus" aria-hidden="true"></i>&nbsp;Add Sales People</button></Link>
                    </div>
                </div>
                {/**First Row Ends*/}
            </div>
        </div>
        <div className='row'>
            <div className='col-lg vasp_second_col text-center'>
                {/** Second Row TABLES */}
                <table className="table table-borderless view_table">
                    <thead>
                        <tr>
                        <th scope="col" className='text-uppercase vasp_th'>Sr. No</th>
                        <th scope="col" className='text-uppercase vasp_th'>Employee Id</th>
                        <th scope="col" className='text-uppercase vasp_th'>Name</th>
                        <th scope="col" className='text-uppercase vasp_th'>Date of Joining</th>
                        <th scope="col" className='text-uppercase vasp_th'>Designation</th>
                        <th scope="col" className='text-uppercase vasp_th'>Reporting To</th>
                        </tr>
                    </thead>
                <tbody>
                    {tbodylist}
                </tbody>
                </table>
                {/**Second Row Ends */}
            </div>
        </div>
      </div>
    )
  }
}

const mapStateToProps = (state)=> ({
    employee:state.employee
})

export default connect(mapStateToProps,{get_all_employees})(withRouter(Attendance));

`

Shubham Pratik
  • 482
  • 2
  • 6
  • 18
  • Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Agney Feb 14 '19 at 12:27

3 Answers3

0

if you want to use the function

<tr onclick={()=>{this.getAttendance}}   key={key}>

like this. Try binding the function inside the constructor.

 constructor(props){
    super(props);
this.getAttendance=this.getAttendance.bind(this);
}

I hope this will work.

Thanks

Sundar Ban
  • 589
  • 5
  • 16
0

I believe the problem is in your for each loop:

Object.keys(allemployee).forEach(function(key) { // HERE
        console.log(key, allemployee[key]);
        let designation = (allemployee[key].designation === 'M')? 'Manager' : (allemployee[key].designation === 'AM') ? 'Assistant Manager' : (allemployee[key].designation === 'LAS') ? 'LAS' : null ;
        let val =    ( <tr onclick={this.getAttendance}   key={key}>
                        <th scope="row" className='text-uppercase vasp_th'>{i}</th>
                        <td  className='text-uppercase vasp_td'>{allemployee[key].employee_id}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].name}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].doj}</td>
                        <td className='text-uppercase vasp_td'>{designation}</td>
                        <td className='text-uppercase vasp_td'>{allemployee[key].reporting_name}</td>
                    </tr>);
            tbodylist.push(val);
            i++;
    });

Declaring a function with the function keyword does not bind the local context, you can try to replace it with:

Object.keys(allemployee).forEach((key) => {

Oscar Franco
  • 5,691
  • 5
  • 34
  • 56
0

Your problem is with the anonymous function inside you

Object.keys(allemployee).forEach(function(key) { // HERE
    console.log(key, allemployee[key]);
    let designation = (allemployee[key].designation === 'M')? 'Manager' : (allemployee[key].designation === 'AM') ? 'Assistant Manager' : (allemployee[key].designation === 'LAS') ? 'LAS' : null ;
    let val =    ( <tr onclick={this.getAttendance}   key={key}>
                    <th scope="row" className='text-uppercase vasp_th'>{i}</th>
                    <td  className='text-uppercase vasp_td'>{allemployee[key].employee_id}</td>
                    <td className='text-uppercase vasp_td'>{allemployee[key].name}</td>
                    <td className='text-uppercase vasp_td'>{allemployee[key].doj}</td>
                    <td className='text-uppercase vasp_td'>{designation}</td>
                    <td className='text-uppercase vasp_td'>{allemployee[key].reporting_name}</td>
                </tr>);
        tbodylist.push(val);
        i++;
});

You are using function(key) which will bind this to the local context. This is not what you want.

You can either put this in a variable before calling Object.keys(allemployee).forEach(...)

const that = this;
Object.keys(allemployee).forEach(key => { // HERE
    //that.getAttendance
});

or you can use a fat arrow function

Object.keys(allemployee).forEach(key => { // HERE
    ...
});
Weedoze
  • 13,683
  • 1
  • 33
  • 63