I'm facing a problem, and I've been trying to find a solution using RxJs
, but can't seem to find one that fits it...
Here is what I thought :
concatMap()
to avoid nested subscriptions and subscribe to each request when the previous one is done.Consider this very simplified version. Assume that each of
represents a whole REST successful request (will handle errors later), and that I will do unshown work with the n
parameter...
const request1 = of('success 1').pipe(
delay(500),
tap(n => console.log('received ' + n)),
);
const request2 = (n) => of('success 2').pipe(
delay(1000),
tap(n => console.log('received ' + n))
);
const request3 = (n) => of('success 3').pipe(
delay(400),
tap(n => console.log('received ' + n))
);
request1.pipe(
concatMap(n => request2(n).pipe(
concatMap(n => request3(n))
))
)
However, when I subscribe to the last piece of code, I will only get the response of the last request, which is expected as the pipe resolves to that.
So with concatMap()
, I can chain my dependent REST calls correctly, but can't follow the progress.
Though I could follow the progress quite easily with nested subscriptions, but I am trying hard to avoid this and use the best practice way.
How can I chain my dependent REST calls, but still be able to do stuff each time a call succeeds ?
The simplest solution would be to have a progress counter variable that is updated from a tap when each response comes back.
let progressCounter = 0;
request1.pipe(
tap(_ => progressCounter = 0.33),
concatMap(n => request2(n).pipe(
tap(_ => progressCounter = 0.66),
concatMap(n => request3(n)
.pipe(tap(_ => progressCounter = 1)))
))
);
If you want the progress itself to be observable then you want to share the request observables as to not make duplicate requests) and then combine them to get the progress.
An example of how you may want to approach that can be found at: https://www.learnrxjs.io/recipes/progressbar.html