0

I have a API call in another file that I am importing into my main file. I want to make a synchronous API call because I cannot use useState hook to set data when response is available (because API is in another file...?). Can I pass the useState hook to the API?

I was under the impression that a promise would not get returned because of async/await use.

enter image description here

As of right now a resolved promise is getting returned to the caller file:

import errorList from "../Static-codes/ErrorList";

export const retrieveBasicUserData = async (usernameFieldValue) => {
  const responseObject = {
    data: null,
    error: {
      exists: false,
      type: null,
    },
  };

  const response = await fetch(
    `https://api.github.com/users/${usernameFieldValue}`
  );
  const responseJSON = await response.json();

  if (response.status == 404) {
    responseObject.error.exists = true;
    responseObject.error.type = errorList.userNotFoundError;
  } else if (response.status === 200) {
    responseObject.data = responseJSON;
  } else if (response.status !== 200 && response.status !== 404) {
    responseObject.error.exists = true;
    responseObject.error.type = errorList.apiGeneralError;
  }
  console.log(responseObject);
  return responseObject;
};


let responseObject = retrieveBasicUserDataAPI(usernameFieldValue);
console.log(responseObject);
vishalkohli
  • 87
  • 1
  • 2
  • 9

2 Answers2

0

Even the call is defined in another file, but as long as you can import it, you should be able to get the response via

  const abc = await retrieveBasicUserData(xxx)

The call is async, but async/await combo will make it look like synchronous.

windmaomao
  • 7,120
  • 2
  • 32
  • 36
0

This is an very common pattern, and can be solved using a combination of useEffect and useState hooks. useCallback is not completely necessary, but does not hurt to memorize the callback.

import doRetrieveBasicUserData from '.../'

const SomeComponent = ({ userName }) => {
  const [loading, setLoading] = useState(false)
  const [userData, setUserData] = useState()

  const retriveBasicUserData = useCallback(async => {
    setLoading(true)
    const data = await doRetrieveBasicUserData(userName)
    setUserData(data)
    setLoading(false)
  }, [doRetrieveBasicUserData])

  useEffect(_ => { retrieveBasicUserData() }, [])

  if (loading) return (<div>Loading ...<div>);
  return (
    <div>JSON.stringify(userData)</div>
  )
}

The reason to not just do:

useEffect(async => {
  setLoading(true)
  const data = await doRetrieveBasicUserData(userName)
  setData(data)
  setLoading(false)
}, [doRetrieveBasicUserData])

... is that async functions return a Promise, and useEffect needs the return value to be a teardown function, not a Promise.

ichigolas
  • 7,595
  • 27
  • 50