Issue
My following code is part of the validation portion of a project. The purpose of this piece of code is to check if a value exists in a reference table. If does exist, then ok to proceed. If not, throw error and stop the user.
saveChanges() {
//blah blah
if (needTovalidate){
passedCheck = false;
this.validationService.checkExistence(value)
.then((exist: boolean) => {
passedCheck = exist;
console.log("INSIDE: " + exist);
});
console.log("OUTSIDE: " + passedCheck);
if(passedCheck) {
//Rest of code
} else {
//Throw error msg
}
}
public async checkExistence(value: string): Promise<boolean>{
var exist = false;
return this.getRefData().then((rec: dataModel[]) => {
return rec.some(el => {
return el.col1 === value;
});
});
}
private async getRefData() {
return await this.configurationService.retrieveTableData().toPromise();
}
Expected Log:
INSIDE: true
OUTSIDE:true
Actual Log:
OUTSIDE: false
INSIDE: true
Obviously, the code did not wait for the boolean promise to resolve before it proceeds to the next line.
Any suggestions?
Solution
As @jfriend00 mentions in your comment discussions that this is a dupe of similar questions, whenever using asynchronous functions (Promise
, Observable
) you should bubble up the asynchronicity back to the call and .then
or .subscribe
it there.
Return value with asynchronous functions in Typescript
Any suggestions?
You could alter your saveChanges
and checkExistence
function in a similar way to this:
Please see the example below and maybe clean up your question example code in an edit (if not rewriting to make a better example question, I believe you at least may resolve your issue yourself in the process by taking the time to go over it painstakingly again)
There are a couple of issues with the pseudocode you have provided, but I tried to conceptualise the process as best I could while remaining true to your original code.
saveChanges(needToValidate: boolean, // ??
changesToValidate: Changes,
asyncValidateFunction: (changes: Changes) => Promise < boolean > , // hmm
) {
asyncValidateFunction(changesToValidate);
//blah blah
if (needToValidate) { // Random context here? Feels like too many things going on in one. Try to isolate functionality.
this.validationService.checkExistence(value)
.then(
(exist: boolean) => {
yourStuffToDoAfterPassedCheckValidation(exist) // hmm
console.log("INSIDE: " + exist); // be safe and stay inside :)
}
);
}
}
// Tried to encapsulate as much as your original concept and style from original question.
// Please refactor this based on your understanding
yourStuffToDoAfterPassedCheckValidation(passedCheckFlag: boolean) {
if (passedCheckFlag) {
// Rest of code
} else {
// Throw error msg
}
}
public checkExistence(value: string): Promise < boolean > {
// Unused junk code? var exist = false;
return this.getRefData()
.then(
(rec: dataModel[]) => {
return rec
.some(el => {
return el.col1 === value;
});
});
}
As this is in Angular, would this perhaps be related to Angular forms? Async validators might be helpful to you even if not directly related
Similar question to Return value with asynchronous functions in Typescript and perhaps many others
I see similar inconsistencies in these types of questions that could be improved with explicit typing in TypeScript
to provide quicker feedback of things to guard against things going wrong!
If you want more specific help, please provide a refactored version of your original code, because some things were seemed weakly replaced.
Otherwise, we could work off pseudocode with more clarity. As this seems to be a a duplicate question making similar async mistakes, it is up to you to provide the context in which your code is not working, otherwise comprehensive answers are already available in the other questions 😊.
In troubleshooting tangled code, it might help you to rewrite the whole program flow as pseudocode first and then regenerate the code based on that to consolidate what you are trying to understand. (This is why I sometimes recommend handwriting your program, or, at the very least, break down everything into assigned variables, explicitly type everything and make as much use of the TypeScript
Language service as you can.
Edit: I see you had already duplicated your own question that is a bit clearer and is working towards fixing your issues. I wish you would've just updated your question in one place though. From the comments in your other questions you do not seem to want to follow suggestions to the fundamental asynchronous usages of Promise
and still want to depend on a mutated value that does not exist yet (asynchronous).
Answered By - mittens pair
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.