The onSubmit callback paymentHandler is supposed to run as soon as the form is submitted, I didn’t specify button type. but as soon as I click submit button, nothing happens until I click the submit button again. The button and form inputs are styled components. They work fine in other pages.
const callPaystack = () => {
fetch('https://api.paystack.co/transaction/initialize', {
method: 'POST',
headers: {
'Authorization': `Bearer ${import.meta.env.VITE_PAYSTACK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: buyerEmail,
amount: totalPrice * 100,
channels: ["card", "bank", "qr", "ussd"],
metadata: {
"cancel_action": "https://crown-storex.netlify.app",
}
}),
}).then((res) => res.json())
.then((data) => {
setPaymentResult(data);
console.log(paymentResult)
})
}
const paymentHandler = async (e) => {
e.preventDefault();
await callPaystack();
location.href = paymentResult.data.authorization_url;
}
<form onSubmit={paymentHandler}>
<FormInput
label="Email"
name="email"
type="email"
value={buyerEmail}
onChange={(e) => setBuyerData({ ...buyerData, buyerEmail: e.target.value })}
required
/>
<Button buttonType={buyerEmail ? "inverted" : "disabled"} >Pay Now With Paystack</Button>
</form>
2
Answers
This should be happening because you are updating the state which updates after paymenthandler is completed entirely.
You should return the value from paymenthandler and use to set location.href
You are not returning the result from the
fetch
your async function. To give a simplified example, what you do is similar like this:What you should be doing is something like this:
So what happens in the second example, is you return the promise from the fetch function, inside the first example you return a promise (async function always return promise) that is not part of your fetch function, and therefore resolves immediately. So my advice is: return the result from
fetch
and then change the URL.NB: One more thing you might try if you don’t want to rewrite your function is use a
useEffect
hook that is part of React, and setpaymentResult
as a depencency. This means wheneverpaymentResult
changes this function runs. Something like this: