I am using React Final Form for creating forms. I have a component where I have defined the Confirm Modal Box and promise to handle it. Function implementation is like below:
function Campaign() {
let resolveConfirm;
let rejectConfirm;
const confirmPromise = new Promise((resolve, reject) => {
resolveConfirm = resolve;
rejectConfirm = reject;
});
const modal = (
<ConfirmModal
name={MODAL_DISABLE_SOCIAL_CAMPAIGNS}
title={t('Confirm Uncheck')}
buttonText={t('Confirm')}
onConfirm={resolveConfirm}
modalEvents={{
onClose: () => {
try {
rejectConfirm();
} catch (e) {}
},
}}
>
<p>{t('Are you sure you want to disable ?')}</p>
</ConfirmModal>
);
return (
<OpenModal modal={modal}>
{(open) => (
<ManageForm
openConfirmModal={({ campaign }, form) => {
const isUnchecked = !campaign?.selected;
// If unchecked the selected checkbox only then
// confirm dialog box should get open
if (isUnchecked) {
open();
return confirmPromise;
}
return false;
}}
>
{(params) => {...
}}
</ManageForm>
)}
</OpenModal>
)
}
The 'ManageForm' Component is imported into the above component 'Campaign' and has a 'save' button which on clicking calls the submission method and confirm modal opens up with options 'cancel' and 'confirm'. Implementation of 'ManageForm' component is like below :
import { Form } from 'react-final-form';
import Button from 'components/UI/Button';
function ManageForm(){
const {
openConfirmModal
} = props;
}
// This runs when clicked on a save button.
const handleSubmit = (formValues, form) => {
if (openConfirmModal) {
const openPromise = openConfirmModal(formValues, form);
if (openPromise) {
try {
await openPromise;
} catch (e) {
// Don't continue if the user cancelled the opening
return;
}
}
}
// Code after this will run only if openPromise is success.
// Here a network call happens via saveEndpoint method
const response = await saveEndpoint({ ...formValues });
}
return (
<Form
onSubmit={handleSubmit}
>
(formProps) => {
return (
<form>
....
<Button
label={t('button_label.save')}
type="submit"
appearance="brand"
/>
....
</form>
)}
</Form>
);
}
Now, the problem occurs when user after cancelling the confirm modal box for the first time, user clicks on save button again and this time if clicks on confirm it doesn't work. If user when lands on the page first time, and clicks on the save button and then clicks on the confirm button, in that case it works. It's just after cancelling once and then on subsequent confirmation it fails.
My findings :
When user cancels for the first time, rejectConfirm gets called and it sets the confirmPromise as rejected which inside the ManageForm's 'openPromise' if block gives await openPromise value as rejected and code stops. Now when user hits save button again, and this time if user tries to click on confirm, resolvePromise gets called but the value of confirmPromise was already set by rejectConfirm (when user cancelled the first time) and still it remains the same, i.e., rejected. So again await openPromise in ManageForm gives us rejection and confirmation doesn't work.
How can I handle the promise to make this work for further subsequent confirm calls when cancelled in the first time ? I cannot re-render my component whenever user cancels the confirmation, as it will remove all the selected form values.
Thanks.