I am trying to fetch a value from an API useEffect:
useEffect(async() => {
try {
const result = await getToken(urlSuffix);
logger.log('returned')
setToken(result);
} catch (error) {
logger.debug('ERROR: ', error);
throw error;
}
}, [urlSuffix]);
The thing is, the token never gets returned by the function, but the fetching part works correctly (I am logging the token). Here is the api fetch:
export const getToken = async (
urlSuffix
) => {
try {
const url = `https://api_url/api/v1/asset/${urlSuffix}`;
const data = await fetch(url, {
headers: {
'Accept': 'application/json',
'X-Api-Key': API_KEY,
},
method: 'get',
timeout: 5000, // 5 secs
});
const token = data?.data?.collection?.token;
logger.debug('TOKEN: ', token);
return token;
} catch (error) {
logger.debug('TOKEN FETCH ERROR');
}
};
The logger.debug
when fetching logs the correct token, but the logger.log
in useEffect
never logs that the results have returned. What is stopping getToken
from returning token
?
CodePudding user response:
You seem to be using fetch() as if it were Axios which it is not.
fetch()
returns a promise that resolves with a Response object which does not have a data
property. I think what you want in your getToken()
function is this...
export const getToken = async (urlSuffix) => {
const url = `https://api_url/api/v1/asset/${urlSuffix}`;
// FYI - fetch does not support timeouts
const res = await fetch(url, {
headers: {
'Accept': 'application/json',
'X-Api-Key': API_KEY,
},
method: 'GET',
});
if (!res.ok) {
logger.debug('TOKEN FETCH ERROR');
throw new Error(`${res.status}: ${await res.text()}`)
}
const data = await res.json() // parse the response stream as JSON
const token = data.collection.token;
logger.debug('TOKEN: ', token);
return token;
}
You should also not pass an async function to useEffect
as it breaks the cleanup process
useEffect(() => {
getToken(urlSuffix).then(setToken)
}, [ urlSuffix ]);
CodePudding user response:
Please note that using a try...catch
inside of useEffect
is a bad practice (see here).
But it seems to me that you set your async
/await
correctly, so it really should work.
Try adding the getToken
function to dependencies of your useEffect
hook.
useEffect(async() => {
try {
const result = await getToken(urlSuffix);
logger.log('returned')
setToken(result);
} catch (error) {
logger.debug('ERROR: ', error);
throw error;
}
}, [urlSuffix, getToken]);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>