I have three components. A parent, a child and a modal component residing inside the child. The modal must show some data fetched from the API (called fetchMyDetails
) and the function resides in the parent. Whenever a button is pressed inside the child, a callback to fetchMyDetails
is called and data should be passed from the parent to the modal. While the data is fetched, a loading prompt appears until the API call is completed.
The problem:
The await
in handleButtonPress
method is ignored and the modal is being opened before the data has completed fetching. Why is that?
My parent component:
const MyParent= () => {
// Date pentru solicitare in curs (nota, absenta stearsa sau modificata etc)
const [myDetails, setMyDetails] = useState<MyDetailsType | null>(null)
const fetchMyDetails = async () => {
dispatch((setGlobalLoadingModal(true))); // This is a global modal for loading prompts residing in App.tsx
myFetchFunction()
.then((response: MyDetailsType) => {
if (response.value.length > 0) {
setMyDetails(response.value)
}
})
.catch(async (error: ApiError) => {
// ...some error catching
}
})
.finally(() => {
dispatch((setIsModalLoadingShown(false)));
})
}
return (
<MyChild myDetails={myDetails} fetchMyDetails={fetchMyDetails}
)
And then I have my child component
const MyChilds= ({fetchMyDetails, myDetails}: Props) => {
const [showMyModal, setShowMyModal=useState<boolean>(false);
const handleButtonPress = async () = > {
// **THE PROBLEM IS HERE**
await fetchMyDetails();
setShowMyModal(true)
}
return (
<>
{showMyModal &&
<MyModal myDetails={myDetails}/>
}
<Button onPress={handleButtonPress}/>
</>
)
3
Answers
You need to make your callback an async function, like so:
I think the issue is that you are not awaiting myFetchFunction, the then clause is triggered after the promise is resolved, but fetchMyDetails returns before that:
You can use try/catch like this. or just add await before myFetchFunction();