I have a dialog component, which executes two async functions on submit. My goal is to keep the dialog opened and show a loading state until both functions are finished. After it, I want to close the dialog.
My submit function, which is defined in parent component, looks like this:
async submit() {
await this.foo1();
await this.foo2();
}
This function is passed as a prop to the dialog component:
<app-dialog @submit="submit" />
In my dialog component, on a button click, I try to do this:
async onClick() {
await this.$emit('submit');
this.closeDialog();
},
However, dialog is closed immediately instead of waiting for submit to be executed. What's the best way to accomplish this?
I managed to find a solution by passing a callback in dialog component:
submit() {
this.$emit('submit', () => this.closeDialog)
},
then using @submit="submit" on the parent component, and defining 'submit' as such:
async submit(closeDialog) {
await this.foo1();
await this.foo2();
closeDialog()
}
But there must be a better solution than this!
There's an alternative pattern for this kind of problem, namely passing a callback function as a prop.
On your dialog component:
props: {
onSubmit: {
type: Function,
required: true // this is up to you
},
[...]
// in your methods
async onClick() {
if (this.onSubmit && typeof this.onSubmit === 'function') {
await this.onSubmit();
}
this.closeDialog();
}
and then, in your parent component:
<app-dialog :on-submit="submit" />
[...]
// in your methods:
async submit() {
await this.foo1();
await this.foo2()
}
It will be important where you handle your promises. For example, if you want to keep the modal open in case of error, you could do error handling in the modal component, or at least forward some error to it.
It's worth exploring validation of the function even more, for instance checking if it really returns a promise and then waiting on it, otherwise do something else.
Even if just by a bit, this pattern will add a bit of coupling to your solution, so you don't want to replace all events with callback functions!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With