1

After setup a simple token login based in a tutorial and the react docs the react-native shows Can't find variable: isLogged i've tried to pass the getToken to isLogged var but show this Can't find variable error.

sorry, as i'm trying to learn js and the react in general terms.

in this case if the token exists redirect the user to home otherwise redirect to login. so, can anyone please spare a hint about how to pass a variable as a function in this scenario?

here is the code:

import React, { Component } from 'react';

import { AsyncStorage } from 'react-native';

import { NativeRouter, Route, Link, Redirect, withRouter } from 'react-router-native'

import Login from './pages/Login';
const AUTH_TOKEN = 'auth_token';
const isLogged = getToken();

class App extends Component {

    componentWillMount() {
        this.getToken();

    }

    async getToken() {
        try {
            let authToken = await AsyncStorage.getItem(AUTH_TOKEN);
            if (!authToken) {
                console.log("Token not set");
            } else {
                this.verifyToken(authToken)
            }
        } catch (error) {
            console.log("Something went wrong");
        }
    }


  async verifyToken(token) {
    let authToken = token

    try {
      let response = await fetch('https://lpfoot.herokuapp.com/api/verify?session%5Bauth_token%5D='+authToken);
      let res = await response.text();
      if (response.status >= 200 && response.status < 300) {
        //Verified token means user is logged in.

      } else {
          //Handle error
          let error = res;
          throw error;
      }
    } catch(error) {
        console.log("error response: " + error);
    }
  }


render() {
    if (isLogged) {
        return this.props.history.push('./pages/Home');
    } else {
        return this.props.history.push('./pages/Login');
    }


}
}



export default App;
  • 2
    getToken() is a method of your App Component you can't use this method outside this class. Verify if user is logged in componentWillMount() only and use the state for your isLogged variable. – Emmanuel RICHE Jul 02 '18 at 21:25
  • @Maestro31 thank you –  Jul 03 '18 at 08:33

1 Answers1

0

A couple of things are wrong in your code:
trying to call a method getToken outside of the scope where it is defined, here, the class App. more about scope.
Second thing: the render method is called once when the class is instantiated and then if a prop or the local state of the class change. In your case changing the value of isLogged won't trigger the render method as isLogged is not part this.props or part of this.state

One way you could do this with react would be:

import React, { Component } from 'react';

import { AsyncStorage } from 'react-native';

import { NativeRouter, Route, Link, Redirect, withRouter } from 'react-router-native'

import Login from './pages/Login';
const AUTH_TOKEN = 'auth_token';

class App extends Component {

    state = {
      isLogged:false
    }

    componentDidMount() {
      this.getToken();
    }

    async getToken() {
        try {
            let authToken = await AsyncStorage.getItem(AUTH_TOKEN);
            if (!authToken) {
                console.log("Token not set");
            } else {
                this.verifyToken(authToken)
            }
        } catch (error) {
            console.log("Something went wrong");
        }
    }

  async verifyToken(token) {
    let authToken = token

    try {
      let response = await fetch('https://lpfoot.herokuapp.com/api/verify?session%5Bauth_token%5D='+authToken);
      let res = await response.text();
      if (response.status >= 200 && response.status < 300) {
        //Verified token means user is logged in.

        this.setState({ isLogged: true });

      } else {
          //Handle error
          let error = res;
          throw error;
      }
    } catch(error) {
        console.log("error response: " + error);
    }
  }


render() {
    if (this.state.isLogged) {
        return this.props.history.push('./pages/Home');
    } else {
        return this.props.history.push('./pages/Login');
    }
  }
}

export default App;

A couple of things:
About react local state:
- state vs props
- a good article about understanding setState .
- avoid using componentWillMount but instead componentDidMount more info

Also render is called everytime a prop or a value of the state is changed, in your case, I guess, you will have issues by pushing to history in a render function. I have not tested it but I would do something like this instead:

inside async verifyToken(token)

 async verifyToken(token) {
    let authToken = token

    try {
      let response = await fetch('https://lpfoot.herokuapp.com/api/verify?session%5Bauth_token%5D='+authToken);
      let res = await response.text();
      if (response.status >= 200 && response.status < 300) {
        //Verified token means user is logged in.

        this.props.history.push('./pages/Home');

      } else {
          //Handle error
          let error = res;
          throw error;
      }
    } catch(error) {
        console.log("error response: " + error);
    }
  }

inside of the render method

render() {
  <Login />
}
Kevin Amiranoff
  • 13,440
  • 11
  • 59
  • 90
  • cool! @kevin-amiranoff first, thank you very much for your help. your answer is great! so the componentDidMount() is the callback to the setState! –  Jul 03 '18 at 08:50
  • 1
    @lula, componentDidMount is call only when the component is mount (insert into the dom's tree). More explanations on the doc : https://reactjs.org/docs/react-component.html#the-component-lifecycle – Emmanuel RICHE Jul 03 '18 at 11:33