Issue
I am trying to implement an httpService where we have 3 Rest API endpoint. If the first API return a success code then I don't want to call the next end point but i case of error i want to try second or third. I have written my code like
import { of, throwError } from 'rxjs'; import { catchError, mergeMap } from 'rxjs/operators';
this.httpService
.post(`${primary_system}?id=${params.id}`)
.pipe(
catchError((primaryError) => {
if (!!secondary_system) {
return this.httpService
.post(`${secondary_system}?id=${params.id}`)
.pipe(
catchError((secondaryError) => {
if (!!tertiary_system) {
return this.httpService.post(`${tertiary_system}?id=${params.id}`);
}
return of(secondaryError);
})
);
}
return of(primaryError);
})
);
certainly the will be a way to flattern these nested calls. I think this is bad practice to pipe Observables like this. Any better solution?
Solution
You do not need to embed the second catchError into the closure of the first catchError.
In other words you can do something like this
this.httpService
.post(`${primary_system}?id=${params.id}`)
.pipe(
catchError((primaryError) => {
if (!!secondary_system) {
return this.httpService
.post(`${secondary_system}?id=${params.id}`)
);
}
return of(primaryError);
}),
// here you catch an error that is generated by the call to the
// secondary system
catchError((secondaryError) => {
if (!!tertiary_system) {
return this.httpService.post(`${tertiary_system}?id=${params.id}`);
}
return of(secondaryError);
})
);
You could also make the code maybe more readable by introducing 2 functions that represent the calls to the secondary and tertiary systems, like this
// this function returns an Observable that represents the call to the
// secondary system if it catches an error coming from upstream
function callSecondIfFirstFail(id: any) {
return pipe(
catchError((primaryError) => {
if (!!secondary_system) {
return this.httpService.post(`${secondary_system}?id=${id}`));
}
return of(primaryError);
}),
)
}
// this function returns an Observable that represents the call to the
// tertiary system if it catches an error coming from upstream
function callThirdIfSecondFail(id: any) {
return pipe(
catchError((secondaryError) => {
if (!!tertiary_system) {
return this.httpService.post(`${tertiary_system}?id=${id}`));
}
return of(secondaryError);
}),
)
}
// this is then how the code that performs the, possible, three calls
// would look like
this.httpService
.post(`${primary_system}?id=${params.id}`).pipe(
callSecondIfFirstFail(params.id),
callThirdIfSecondFail(params.id)
)
This stackblitz tries to represent this idea.
Answered By - Picci
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.