Can you help me understand why this doesn't work:
I'm working in Aurelia, and I try to validate some input data using the validation controller, which is documented here: https://aurelia.io/docs/plugins/validation#validation-controller
Now, I have a map of this data, where I need to evaluate each entry, and I want to create an array, where each item contains the validation result of each entry, and when everything is done, return the array.
So something like this (simplified):
function ValidateAll(InputDataMap){
let validationResults = new Array();
InputDataMap.forEach((item) => {
validationResults.push(validateEntry(item));
});
return validationResults;
}
function validateEntry(item){
(aurelia's validation)controller.validate(item, "some value", "some rule")
.then(result => {
return result;
});
}
Now, this will not work of course, because I need to wait for the validation controller to resolve it's promise before I can get any data back, and so far I've failed at that.
I read that if you use the async/await keyword it will pause a function until the promise has been resolved, so I made changes, something like this:
function ValidateAll(InputDataMap){
let validationResults = new Array();
InputDataMap.forEach(async(item) => {
let result = await validateEntry(item);
validationResults.push(result);
});
Now, this doesn't work either, and that's what I'm wondering about. I suppose that my "validateEntry" function is considered finished by the "await" once it's run, and doesn't wait for the "validate()" function's promise inside "validateEntry" to be resolved. Can I write it as simply as this with a few modifications and still get it to work?
You have to return a Promise from your validateEntry
:
function validateEntry(item){
return controller.validate(item, "some value", "some rule")
}
A then
just returning its parameter is not required, and does nothing, so .then(result => { return result; })
can be removed.
The async
callback for the forEach
would not make ValidateAll
to wait for the validation. You have to wait for all Promises to be resolved, and return a Promise from ValidateAll
, the forEach
can be replaced by map
so that you don't need to do the push manually:
let validationResults = new Array();
validationResults = InputDataMap.map(item => validateEntry(item));
You don't need async
here because you do not need an await
here. Now validationResults
contains a list of Promises. You now need to use Promise.all
to wait until those are resolved.
function ValidateAll(InputDataMap){
let validationResults = InputDataMap.map(item => validateEntry(item));
return Promise.all(validationResults);
}
Now ValidateAll
will return a Promise that will resolve with an array containing the results of the validation.
You could shorten the code even more to:
function ValidateAll(InputDataMap){
return Promise.all( InputDataMap.map(validateEntry) );
}