Rida Rezzag
Rida Rezzag

Reputation: 3943

React Class how to return a Boolean after a promise fetch call

hello i have this class when i call Auth.isAuthenticated() from another component in react, it always return false (its the default value), even if the server return a 200 response, witch sets this.authenticated = true . how do i use promises to make the method wait till the fetch call is finished then return the result

Edit: i need the Boolean true or false to be returned so based on that, i can show or hide the component, all answers are helpful but i need a Boolean not a promise any help please

    class Auth {
    constructor() {
        this.authenticated = false;
    }


    isAuthenticated() {
        //get token from local storage if there is one
        const jwttoken = localStorage.getItem('jwttoken');
        const bearer = 'Bearer ' + jwttoken;
        const data = new FormData();
        // get the website backend main url from .env
        const REACT_APP_URL = process.env.REACT_APP_URL
        fetch(`${REACT_APP_URL}/api/auth/verify`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Authorization': bearer,
            },
            body: data
        }).then(
            (response) => {
                response.json()
                    .then((res) => {
                        if (response.status === 200) {
                            this.authenticated = true;
                        }
                        if (response.status === 401) {
                            localStorage.removeItem('jwttoken');
                            this.authenticated = false;
                        }
                    })
            }
        ).catch((err) => {
            // console.log(err)
        });

        return this.authenticated;
    }


}



export default new Auth();

and from another component i call Auth.isAuthenticated() === true

export const PrivateRoute = ({ component: Component, ...rest }) => {

  return (
    <Route {...rest} render={(props) => (
      Auth.isAuthenticated() === true
        ? <Component {...props} />
        : <Redirect to='/admin' />
    )} />
      )
}

Upvotes: 3

Views: 9519

Answers (3)

Dupocas
Dupocas

Reputation: 21307

Let's say you want to write a function that returns a promise and resolves when some action finishes (an API call for example). You could write something like this:

const myAsyncFunction = () =>{
    return new Promise((resolve, reject) =>{
        //Faking an API Call
        setTimeout(() => resolve('data'), 400)
    })
}

There you go! Now you have a function that returns a promise which will resolve in 400ms. Now you need to use either .then() method or async await statements.

const sideEffects = async () =>{
    const result = await myAsyncFunction()
    console.log(result) //'data'
}

Upvotes: 5

Isaac Vidrine
Isaac Vidrine

Reputation: 1666

If you don't want to do async/await you can have isAuthenticated return a promise.

isAuthenticated() {
  return new Promise((resolve, reject) => {
    //get token from local storage if there is one
        const jwttoken = localStorage.getItem('jwttoken');
        const bearer = 'Bearer ' + jwttoken;
        const data = new FormData();
        // get the website backend main url from .env
        const REACT_APP_URL = process.env.REACT_APP_URL
        fetch(`${REACT_APP_URL}/api/auth/verify`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Authorization': bearer,
            },
            body: data
        }).then(
            (response) => {
                response.json()
                    .then((res) => {
                        if (response.status === 200) {
                            resolve(true)
                        }
                        if (response.status === 401) {
                            localStorage.removeItem('jwttoken');
                            resolve(false)
                        }
                    })
            }
        ).catch((err) => {
            // reject(err)
        });
  })        
}

And inside an async function you could do let isAuthenticated = await isAuthenticated() or you can use .then and .catch outside of async function to return result

Upvotes: 2

AlexZvl
AlexZvl

Reputation: 2302

use await async

async isAuthenticated() {
        //get token from local storage if there is one
        const jwttoken = localStorage.getItem('jwttoken');
        const bearer = 'Bearer ' + jwttoken;
        const data = new FormData();
        // get the website backend main url from .env
        const REACT_APP_URL = process.env.REACT_APP_URL
        const response = await fetch(`${REACT_APP_URL}/api/auth/verify`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Authorization': bearer,
            },
            body: data
        });

        const responseToJson = await response.json();

         if (responseToJson.status === 200) {
             this.authenticated = true;
         }
         if (responseToJson.status === 401) {
             localStorage.removeItem('jwttoken');
             this.authenticated = false;
         }

       return this.authenticated;
    }

Upvotes: 0

Related Questions