I have code, that checking status and if status is not Completed or Failed, retry call
Here is code
getRecognitionById() {
this.loaderService.show(null, true);
this.vendorWebApiService
.createRecognition(this.executiveChangeId)
.pipe(take(1))
.subscribe((res) => {
this.refresher$ = interval(5000);
this.refreshSub = this.refresher$.subscribe(() => {
this.checkStatus(res.taskRequestId);
if (this.jobStatus === "Completed") {
this.refreshSub.unsubscribe();
this.getLatestFeedback();
this.loaderService.hide(true);
}
if (this.jobStatus === "Failed") {
this.loaderService.hide(true);
this.refreshSub.unsubscribe();
alert("Recognition failed. Try again later");
} else {
if (this.checkCount < 36) {
this.checkStatus(res.taskRequestId); //run check status again only when we get response
} else {
this.loaderService.hide(true);
this.refreshSub.unsubscribe();
alert("Recognition failed. Try again later");
}
}
});
});
}
I need to wait for response from checkStatus() method and only then run checkStatus() again (I commented part of code where I need to achieve this logic)
Here is code of checkStatus method
checkStatus(taskRequestId: number) {
this.checkCount++;
this.vendorWebApiService
.getRecognition(taskRequestId, this.executiveChangeId)
.pipe(take(1))
.subscribe((recognitionResponse) => {
this.jobStatus = recognitionResponse.jobStatus;
if (recognitionResponse.jobStatus === "Completed") {
this.recognitionData = recognitionResponse;
}
});
}
How I can achieve this?
You have a lot of extra bits in your code, so I doubt this would compile as-is. Even so, here's an idea for something that should work if you iron out the kinks.
// By returning an observable that emits once the status is checked,
// we use emission to know when the status is checked.
checkStatus(taskRequestId: number): Observable<Status> {
return this.vendorWebApiService.getRecognition(
taskRequestId,
this.executiveChangeId
).pipe(
take(1),
/* This info is emitted directly into your stream now, so
// you shouldn't need to se global variables here anymore.
// uncomment this to get those gloabls being set again.
// Up to you.
tap(recognitionResponse => {
this.jobStatus = recognitionResponse.jobStatus;
if (recognitionResponse.jobStatus === "Completed") {
this.recognitionData = recognitionResponse;
}
})
*/
);
}
getRecognitionById() {
this.loaderService.show(null, true);
this.vendorWebApiService.createRecognition(this.executiveChangeId).pipe(
switchMap(res => this.checkStatus(res.taskRequestId).pipe(
tap(({jobStatus}) => {
if (jobStatus !== "Completed" && jobStatus !== "Failed") {
throw "This is an error we can catch and retry with";
}
}),
// If there's an error try again
retryWhen(errors => errors.pipe(
take(36), // Retry a max of 36 times
s => concat(s, defer(() => {
// After 36 retry attempts, we still failed
this.loaderService.hide(true);
alert("Recognition failed. Try again later");
return EMPTY;
})),
delay(5000) // Wait 5 seconds before retry
))
)),
take(1)
).subscribe(recognitionResponse => {
const {jobStatus} = recognitionResponse;
if (jobStatus === "Completed") {
this.recognitionData = recognitionResponse;
this.getLatestFeedback();
}
if (jobStatus === "Failed") {
alert("Recognition failed. Try again later");
}
this.loaderService.hide(true);
});
}