I want to run hideSaveCancel() and loadPage()
after an array of forms has been iterated, during which, each form will be the subject of an async call to insert/update in the database, initiated by the line postObject.preparePost(formData)
Array.from(document.querySelectorAll('form.dirty')).forEach(
f => {
postObject = new Object();
formData = buildFormDataObject(f);
eval(`postObject = ${f.dataset['jsobj']}`);
postObject.preparePost(formData);
}
)
}).then(() => {
hideSaveCancel();
loadPage(postSavePage, postSaveArgs);
});
I don't understand whether I require multiple promises (one for the array and another for the async calls) or one for the whole process, and ...
I need to understand how to send the "completion" message, so that the hideSaveCancel and loadPage are called after all the form updates have completed.
CodePudding user response:
I'd approach it like so...
let requests = [];
[...document.querySelectorAll('form.dirty')].forEach(form => {
const formData = buildFormDataObject(form);
const postObject = form.dataset['jsobj'];
requests.push(postObject.preparePost(formData));
});
Promise.all(requests).then(() => {
hideSaveCancel();
loadPage(postSavePage, postSaveArgs);
});
Basically building an array of all your requests and using Promise.all()
to resolve once all have completed. This approach allows you to implement better error handling for each response (if you wanted).
Note: I removed your eval
statement for the sake of this answer because it's an enormous security risk.
CodePudding user response:
Something like this?
Promise.all(
Array.from(document.querySelectorAll('form.dirty')).map(
f => {
postObject = new Object();
formData = buildFormDataObject(f);
eval(`postObject = ${f.dataset['jsobj']}`);
// return the promise
return postObject.preparePost(formData);
}
)
)
.then(() => {
hideSaveCancel();
// you can chain it even further if you return the promise
return loadPage(postSavePage, postSaveArgs);
})