Reputation: 3943
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
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
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
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