I can find plenty of examples with chaining two calls but i have 3 http calls to make one after another using data from the previous call.
I have two working using flatMap
so:
call1(params)
.flatMap((res1)=> {
return call2(params)
.subscribe(r=>r...)
But for three calls i am trying the same thing but i don't think you can chain flatMaps together?
call1(params)
.flatMap((res1)=> {
return call2(params)
.flatMap((res2)=> {
return call3(params)
.subscribe(r=>r...)
I get an error saying subscription is not assignable to type observation input. Each of those call1 returns an observable from an http operation.
Can anyone point me in the right direction?
Would really appreciate it as it's driving me nuts!
thanks
Paul
You can use flatMap
as many times as you want. However, you have to return an Observable each time.
E.g.
myFunc() // returns an Observable of type X
.flatMap((res: X) => {
// returns an Observable of type Y
})
.flatMap((res: Y) => {
// returns an Observable of type Z
})
.flatMap((res: Z) => {
// returns an Observable of type Q
})
.subscribe((res: Q) => {
// some logic
});
RxJs has changed
Starting from RxJs v5.5, there came Pipeable
operators. We, no longer, prototype some operators to Observable
s, instead we import them and use them as follows:
import { flatMap } from 'rxjs/operators';
myFunc() // returns an Observable of type X
.pipe(
flatMap((res: X) => {
// returns an Observable of type Y
}),
flatMap((res: Y) => {
// returns an Observable of type Z
}),
flatMap((res: Z) => {
// returns an Observable of type Q
})
).subscribe((res: Q) => {
// some logic
});
flatMap()
expects an Observable
as an return value, but you return an Subscription
.
Fix it like this:
call1(params)
.flatMap((res1)=> {
return call2(params);
})
.flatMap((res2)=> {
return call3(params);
})
.subscribe(r=>r...)
Additional note:
These request will still be executed after each other, not in parallel. If you want to speed this up, you could use Observable.forkJoin()
:
Observable.forkJoin(
call1(params),
call2(params),
call3(params)
).subscribe((responses) => {
// responses[0] -> response of call1
// responses[1] -> response of call2
// responses[2] -> response of call3
})