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");
}
};
2
Answers
You can use
Promise.all
to wait for an array ofPromise
s to be completed. (Array#forEach
is not designed to work withPromise
s.)Here, we can use
Array#map
to create an array containing aPromise
for each element in the array returned bygetLineNumbers()
.Each individual asynchronous operation appears to internally
await
, but nothing is awaiting all of those operations. More literally,saveInvoice
isasync
but it doesn’tawait
anything.You can replace the call to
.forEach()
with a call to.map()
to return the promises:Then await those promises: