window.location.href cancels async calls to API

Advertisements

When the code runs window.location.href kicks in before all async calls to the API is done. If I set a breakpoint on the location it works fine.

How can wait until all calls are done before invoking window.location.href?

Code:

const saveInvoice = async () => {
    if (containsItems()) {
        let customerId = document.getElementById("Customer").value;
        let date = document.getElementById("Date").value;
        let dueDate = document.getElementById("DueDate").value;
        let msgKID = document.getElementById("MSG").value;
        let accountId = document.getElementById("Account").value;
        let data = await WebRequest("InvoiceAPI", "CreateInvoiceAsync", null, { "CustomerId": customerId, "Date": date, "DueDate": dueDate, "MsgKID": msgKID, "AccountId": accountId });

        getLineNumbers().forEach(async (nr) => {
            let prodId = parseInt(document.querySelector('select.prod[data-id=\"' + nr + '\"]').value);
            let descr = document.querySelector('input.description[data-id=\"' + nr + '\"]').value;
            let price = parseFloat(document.querySelector('span.price[data-id=\"' + nr + '\"] > span.sum').innerHTML);
            let mva = parseInt(document.querySelector('span.mva[data-id=\"' + nr + '\"] > span.sum').innerHTML);
            let mvaSum = parseFloat(document.querySelector('input.mva-value[data-id=\"' + nr + '\"]').value)
            let count = parseInt(document.querySelector('input.count[data-id=\"' + nr + '\"]').value);
            let perc = parseInt(document.querySelector('input.perc[data-id=\"' + nr + '\"]').value);
            let sum = parseFloat(document.querySelector('#Lines > div.line.row > div.amount-wrap[data-id=\"' + nr + '\"] span.line-sum').innerHTML);

            await WebRequest("InvoiceAPI", "CreateInvoiceLineAsync", null, { "InvoiceId": data.json.id, "ProductId": prodId, "Description": descr, "Count": count, "Discount": perc, "Price": price, "Mva": mva, "MvaSum": mvaSum, "Sum": sum });
        });

        window.location.href = "View/" + data.json.uId;
    }
    else {
        document.getElementById("InvoiceErrorWrap").classList.remove("hide");
    }
};

>Solution :

You can use Promise.all to wait for an array of Promises to be completed. (Array#forEach is not designed to work with Promises.)

Here, we can use Array#map to create an array containing a Promise for each element in the array returned by getLineNumbers().

await Promise.all(getLineNumbers().map(async nr => {
    // other code...
    await WebRequest("InvoiceAPI", "CreateInvoiceLineAsync", null, { "InvoiceId": data.json.id, "ProductId": prodId, "Description": descr, "Count": count, "Discount": perc, "Price": price, "Mva": mva, "MvaSum": mvaSum, "Sum": sum });
}));
// set location here

Leave a ReplyCancel reply