I have method in component that getting data from back end and check statuses
Here is it
getRecognitionById() {
this.loaderService.show(null, true);
this.vendorWebApiService
.createRecognition(this.executiveChangeId)
.pipe(take(1))
.subscribe((res) => {
this.vendorWebApiService
.getRecognition(res.taskRequestId, this.executiveChangeId)
.pipe(take(1))
.subscribe((recognitionResponse) => {
if (recognitionResponse.jobStatus === "completed") {
this.recognitionData = recognitionResponse;
this.getLatesFeedback();
}
if (recognitionResponse.jobStatus === "failed") {
alert();
} else {
}
});
});
}
In this part I check status
this.vendorWebApiService
.getRecognition(res.taskRequestId, this.executiveChangeId)
.pipe(take(1))
.subscribe((recognitionResponse) => {
if (recognitionResponse.jobStatus === "completed") {
this.recognitionData = recognitionResponse;
this.getLatesFeedback();
}
if (recognitionResponse.jobStatus === "failed") {
alert();
} else {
}
});
But problem that if status is another then complete or failed, I need to rerun this logic again every 5 seconds , so every 5 seconds I need to check status and after 10's try, I need to show alert.
How I need to rewrite my code to achieve this logic?
CodePudding user response:
You can do this with rxjs
import { interval, Subject, Subscription } from 'rxjs';
refresher$: Observable<number>;
refreshSub: Subscription;
jobStatus: string = "init"
checkCount = 0
checkStatus() {
this.checkCount
this.vendorWebApiService
.getRecognition(res.taskRequestId, this.executiveChangeId)
.pipe(take(1))
.subscribe((recognitionResponse) => {
jobStatus = recognitionResponse.jobStatus
this.recognitionData = recognitionResponse
});
}
getRecognitionById() {
this.loaderService.show(null, true);
this.checkStatus()
}
this.refresher$ = interval(5000); // every5 sec
this.refreshSub = this.refresher$.subscribe(() => {
this.checkStatus()
if (this.jobStatus === 'completed') {
this.getLatesFeedback();
}
if (this.jobStatus === 'failed') {
alert()
} else {
if (this.checkCount == 10) {
alert()
}
}
});
CodePudding user response:
You can achieve that this way:
Define a counter variable.
Define an interval with a 5000ms timer and reference it to a variable.
Clear interval on success.
Re-run interval on failure and a counter of
counter < 10
.
let counter = 0;
let interval = setInterval(() => {
// ajax().next(() => {
// clearInterval(interval);
// }).catch(() => {
// if (counter >= 10) {
// clearInterval(interval);
// } else {
// counter ;
// }
// })
}, 5000);
- Do NOT forget to clear your interval in
ngOnDestroy
to prevent your app from crash in some scenarios.
CodePudding user response:
With observables you could try something like this
getRecognitionById() {
// this.loaderService.show(null, true);
const ATTEMPT_COUNT = 10;
const DELAY = 5000;
this.vendorWebApiService
.createRecognition(this.executiveChangeId)
.pipe(take(1),
mergeMap((res) => (
this.vendorWebApiService
.getRecognition(res.taskRequestId, this.executiveChangeId)
.pipe(take(1),
))), map((recognitionResponse: any) => {
if (recognitionResponse.jobStatus === "completed") {
this.recognitionData = recognitionResponse;
this.getLatesFeedback();
}
if (recognitionResponse.jobStatus === "failed") {
alert();
} else {
throw { error: 'failed' };
}
}), retryWhen(errors => errors.pipe(
scan((errorCount, err: any) => {
if (err.error === 'failed' || errorCount >= ATTEMPT_COUNT) {
// add code for alert after 10 retries
}
return errorCount 1;
}, 0),
delay(DELAY),
)));
}