Home > database >  How to prevent closing bootbox while using async function?
How to prevent closing bootbox while using async function?

Time:10-31

What Im trying to get is if user get any validation error, then bootbox will show that "this is required". Till now, I've achieved this. But the main problem is that - it's closing the window of boot box if user clicks "Yes" button. I'm getting this because I had to use g async callback in bootbox. For this reason, even after returning false, the bootbox is closing. But I want users to show the box till they press cancel button. If they click Yes then it should shows the validation, with the box is opend. this is my code:

        bootbox.confirm({
            message: 'Test',
            buttons: {
                confirm: {
                    label: 'Yes',
                    className: 'btn-primary'
                },
                cancel: {
                    label: 'No',
                    className: 'btn-danger'
                }
            },
            callback: async function (result) {
                var isValid = $('#form').valid();
                if (result && !isValid) {
                    return false; //it's not working. It's closing the bootbox
                }
                if (result && isValid) {
                    var data = await self.createData(); /* for this 
await function I had to use async callback. without this bootbox is opend*/
                    $.ajax({
                        type: "POST",
                        success: function (result) {

                        },
                    }).then(function () {
                    });
                }
            }
        });

How can I resolve this? Thanks in advanced

CodePudding user response:

It does not appear to me that bootbox.confirm() has any sort of support for async callbacks like you are trying to use. The bootbox closes when your callback returns which will be at the point you hit your first await unless you explicitly return false, but an async callback function ALWAYS returns a promise which is not explicitly false. You cannot change that.

What you can do is make your callback a regular callback function, not async that can return false if validation fails and then create an embedded async function where you can use await that you call from within that first callback like is shown below. Note that the bootbox will close before your asynchronous code completes so if there are any errors in the bootbox code, you will need to new way to present those errors, perhaps putting up a new bootbox. Here's one way to do this code while still using await.

bootbox.confirm({
    message: 'Test',
    buttons: {
        confirm: {
            label: 'Yes',
            className: 'btn-primary'
        },
        cancel: {
            label: 'No',
            className: 'btn-danger'
        }
    },
    callback: function (result) {
        var isValid = $('#form').valid();
        if (result) {
            if (!isValid) {
                // keep prompt open until user presses Cancel
                return false;
            }

            async function run() {
                const data = await self.createData();
                const result = await $.ajax({ ... });
                // do something with result
            }
            // now call async function here (dialog will close)
            run().catch(err => {
                // do something with an error here
                console.log(err);
            });
        }
        return true;
    }
});

Alternatively, you could avoid using await and only use .then() and .catch() and then you wouldn't need this extra layer of function:

bootbox.confirm({
    message: 'Test',
    buttons: {
        confirm: {
            label: 'Yes',
            className: 'btn-primary'
        },
        cancel: {
            label: 'No',
            className: 'btn-danger'
        }
    },
    callback: function (result) {
        var isValid = $('#form').valid();
        if (result) {
            if (!isValid) {
                // keep prompt open until user presses Cancel
                return false;
            }

            self.createData().then(data => {
                return $.ajax({ ... }).then(result => {
                    // do something with result
                });
            }).catch(err => {
                // do something with error here
                console.log(err);
            });
        }
        return true;
    }
});
  • Related