Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot read property 'function' of undefined

I am trying to call a function from another function in my React app. But I keep this error: Error in login TypeError: Cannot read property 'loadDashboard' of undefined. I searched for similar cases all I could find was (1) That I have to use this keyword (2) I have to mention the function inside constructor. I have done both then why I keep getting the error??
My code:

import React, { Component } from 'react';
import '../App.css';
var axios = require('axios');

class Login extends Component {
  constructor(){
    super();
    this.loadDashboard = this.loadDashboard.bind(this);
  }

  loadDashboard(token){
    axios({
      method:'get',
      url:'http://localhost:3000/api/dashboard',
      data: {
        Authorization: token
      },
      responseType:'stream'
    })
     .then(function (response) {
       console.log(response);
     })
     .catch(function (error) {
       console.log("Error in loading Dashboard "+error);
     });
  }

  handleOnSubmit = () => {
     console.log("submittwed");
     axios({
       method:'post',
       url:'http://localhost:3000/authenticate',
       data: {
         email: '[email protected]',
         password: 'apple'
       },
     })
      .then(function (response) {
        var token = response.data.auth_token;
        console.log(token);
        this.loadDashboard(token);
      })
      .catch(function (error) {
        console.log("Error in login "+error);
      });
   }

  render() {
    return (
      <div>
         Username: <input type="email" name="fname" /><br />
         Password: <input type="password" name="lname" /><br />
         <button onClick={this.handleOnSubmit}>LOG IN</button>
      </div>
    );
  }
}

export default Login;        

NOTE: Without loadDashboard, handleOnSubmit function works just fine.

Also, why changing loadDashboard(token){..} to function loadDashboard(token){..} gives me Unexpected token error?

like image 977
noobie Avatar asked Mar 05 '26 00:03

noobie


2 Answers

you could use the arrow function to have the correct this context in your callback:

.then((response) => {
    var token = response.data.auth_token;
    console.log(token);
    this.loadDashboard(token);
  })

You could also do something like this, but arrow function are way smoother:

axios.get("/yourURL").then(function(response) {
  this.setState({ events: response.data });
}.bind(this));
like image 147
user2520818 Avatar answered Mar 06 '26 13:03

user2520818


The smoothest way is to use arrow functions whenever you define a function:

loadDashboard = (token) => {//Note the arrow function
    axios({
      method:'get',
      url:'http://localhost:3000/api/dashboard',
      data: {
        Authorization: token
      },
      responseType:'stream'
    })
     .then((response) => { //Note the arrow function
       console.log(response);
     })
     .catch((error) => {//Note the arrow function
       console.log("Error in loading Dashboard "+error);
     });
  }

This way you don't need to bind your functions in your constructor and don't loose the context of this.

like image 44
Nocebo Avatar answered Mar 06 '26 12:03

Nocebo