Lightning-Web-Components – LWC Async Function Returning Early

asynchronousjavascriptlightning-web-components

This may be an obvious question. It seems like it should be, but I haven't used async/await before. I have the below code

removeProduct(event) {
        let removeProduct = this.checkRemoveProduct();
        console.log('removeProduct: ' + removeProduct);
}


async checkRemoveProduct() {
    const result = await LightningConfirm.open({
        message: 'Are you sure you want to remove this product?',
        variant: 'headerless',
    });
    console.log('result: ' + result);
    return result;
}

The console logs from this are

removeProduct: [object Promise] //Promise is pending here

result: true

Why is the async method forcing a return without hitting any return line? Is there any way to get it to actually wait for the response before returning?

I realize I can write my code in a single function or chain calls, but I would really prefer to break it out if possible–and if nothing else understand why this happens.

Best Answer

Why is the async method forcing a return without hitting any return line?

That's the default behavior of async function: an async function always returns a Promise which will be resolved with the value returned by the async function. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.

Is there any way to get it to actually wait for the response before returning?

Yes and you already used it in checkRemoveProduct function: you have to await the async function. Let me quote the documentation:

Await expressions make promise-returning functions behave as though they're synchronous by suspending execution until the returned promise is fulfilled or rejected. The resolved value of the promise is treated as the return value of the await expression

So you could make removeProduct async in order to use await:

async removeProduct(event) {
    let removeProduct = await this.checkRemoveProduct();
    console.log('removeProduct: ' + removeProduct);
}

You could also handle it with a then():

removeProduct(event) {
    this.checkRemoveProduct()
    .then((removeProduct) => {
        console.log('removeProduct: ' + removeProduct);
    })
}

Or you could handle the promise returned by LightningConfirm.open with then()

removeProduct(event) {
    this.checkRemoveProduct()
}

checkRemoveProduct() {
    LightningConfirm.open({
        message: 'Are you sure you want to remove this product?',
        variant: 'headerless',
    })
    .then((result) => {
        if (result) {
            // OK was clicked
            // here you can call a function that handle this case
            // i.e. this.deleteProduct()
        } else {
            // Cancel was clicked
        }
    })
    return result;
}
Related Topic