Home > OS >  API Query fetch works, doesn't return result though
API Query fetch works, doesn't return result though

Time:11-08

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>

  • Related