I have a function with a popup dialog window with button. I want to wait with executing the rest of the function until the button is clicked. I tried it with Promise and AddEventListener, but cannot find out why is it not working. Could someone help me? (I use Vue3 and Quasar) I have an error for "const confirm" - Object is possibly 'null'.ts(2531) Thank you for any advices.
Here is a part of my template:
<q-dialog persistent v-model="phoneDialogBank">
<q-card>
<q-card-section>
<div class="items" v-for="formField in dynamicDialogFieldsVisible" :key="formField?.Key">
<dynamic-form-field :form-field="formField"></dynamic-form-field>
</div>
<div class="row items-center justify-center">
<q-btn color="primary" class="confirm-phone-dialog" v-close-popup>
{{ t('signing-table.phoneDialogBank.ok') }}
</q-btn>
</div>
</q-card-section>
</q-card>
</q-dialog>
Here is my function:
async function dynamicDialogBeforeSubmit() {
const params = getParamsFromAdvisorDeviceBoolean();
if (params && params.hasOwnProperty('dialogBeforeSubmit') && params.dialogBeforeSubmit) {
phoneDialogBank.value = true;
const confirm = document.querySelector('.confirm-phone-dialog');
const waitForButtonClick = new Promise((resolve) => { confirm.addEventListener('click', resolve); });
await waitForButtonClick.then(() => {
dynamicDialogSave();
});
return;
}
dynamicDialogSave();
}
That error is because your button is within a dialog that renders conditionally. So if there is no dialog, that DOM element does not exist. I'm curious why you are not using some of the great features of Vue? Like putting the click handler on the element and using refs to target the DOM instead of using query selectors and event listeners.
<q-btn color="primary" class="confirm-phone-dialog" @click.prevent="dynamicDialogBeforeSubmit" v-close-popup>
{{ t('signing-table.phoneDialogBank.ok') }}
</q-btn>
Your function is a bit mixed up between async and Promises. async / await
is just syntactic sugar for a Promise. The way you have it written now, you are wrapping a Promise within another Promise.
async function dynamicDialogBeforeSubmit() {
const params = getParamsFromAdvisorDeviceBoolean();
if (params && params.hasOwnProperty('dialogBeforeSubmit') && params.dialogBeforeSubmit) {
phoneDialogBank.value = true;
await dynamicDialogSave();
} else {
console.log('There was a problem')
}
}
I should note that you will likely need to pass an object to dynamicDialogSave(someObject)
for it to actually save something. I assume this, not knowing what that function actually looks like.
Event listeners are not asynchronous and you wouldn't want to wrap them in a promise anyways. If you wish to write it as you have, it would be best to declare the click listener as a separate function that fires onMounted, then call it from any async function. You should also detach native event listeners onUnmounted to avoid memory leaks with Vue.