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?
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 ]);
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]);