I wanted to navigate from one route to another route with the result of http post method. But the navigation is happening without the response from http post. The response is getting later when i debugged the code
How can i fix this ? is there any way to wait the execution till the response comes from backend ?
when i click on a button, a function will execute and a http post call will happen then i need to pass the response from the post request to a new route
Quiz.service.ts
getResult(answers: QuestionAnswer): Observable<number> {
return this.http.post<number>(`${this.API_URL}result`, answers);
}
exam.component.ts
submitQuiz() {
this.isSubmitted = true;
const answers: QuestionAnswer = new QuestionAnswer(Array.from(this.selectedAnswers.keys()), Array.from(this.selectedAnswers.values()));
let result: number;
this.quizService.getResult(answers).subscribe(data => {
console.log(data);
result = data;
});
console.log(result);
this.navigateToResult(result);
}
navigateToResult(result: number) {
if(result != undefined){
const navigationExtras: NavigationExtras = {
queryParams: {
"result" : JSON.stringify(result)
}
}
this.router.navigate(['result'], navigationExtras);
}
}
the value undefined is passed into the route
The returning of the observable value from getResult()
method is an asynchronous operation. Because of that, the initial block of code you have written will fail as result
will be undefined at that point. To further understand this, you should read up on JavaScript's event loop.
You should do this instead - basically, you handle the routing within the subscribe block such that it will only be called after the subscription has been completed. This way, result
will contain a value (instead of being undefined), and navigateToResult()
will be successfully executed since it is supplied with a valid parameter.
submitQuiz() {
this.isSubmitted = true;
const answers: QuestionAnswer = new QuestionAnswer(Array.from(this.selectedAnswers.keys()), Array.from(this.selectedAnswers.values()));
let result: number;
this.quizService.getResult(answers).subscribe(data => {
result = data;
console.log(result);
this.navigateToResult(result);
});
}
submitQuiz() {
this.isSubmitted = true;
const answers: QuestionAnswer = new QuestionAnswer(Array.from(this.selectedAnswers.keys()), Array.from(this.selectedAnswers.values()));
let result: number;
this.quizService.getResult(answers).subscribe(data => {
console.log(data);
result = data;
//move inside subscribe
console.log(result);
this.navigateToResult(result);
});
}
navigateToResult(result: number) {
if(result != undefined){
const navigationExtras: NavigationExtras = {
queryParams: {
"result" : JSON.stringify(result)
}
}
this.router.navigate(['result'], navigationExtras);
}
}
I have made changes to the above code. Move the code inside subscribe since the way Angular works is on the basis of Event loop and anything outside the subscribe event is a separate event keeps continued to be execute.