Reputation: 13008
I have this method:
zip(
this.$one.getOne(id)
.pipe(switchMap(oneResult => {
return this.$two.getTwo(oneResult.id)
}))
.pipe(switchMap(twoResult => {
// Here I Would like to use the **oneResult** as argument to the $three observable too.
return this.$three.getThree(oneResult.id)
})),
this.$four.getFour()
).subscribe(zipResult => {
[getTwoResult, getThreeResult]
}
How do I pass the $one
Observable result to $two
Observable and $hree
observable? I can just get it on the first switchMap.
Upvotes: 4
Views: 4218
Reputation: 38847
You an use map
on the switchMap
to create a "resultSelector". switchMap has a resultSelector function that can be used to create the same effect, but this may get deprecated in future versions of RxJS in lieu of using map
as the below answer demonstrates. You'd effectively be packaging oneResult
and twoResult
into an object or array for use in the second switchMap
. You could keep doing this as far down the stream as you'd need. It would look like something like this (I've added delays to simulate API calls):
import { Component } from '@angular/core';
import { Observable, of, zip } from 'rxjs';
import { map, switchMap, delay } from 'rxjs/operators';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
name = 'Angular';
getOne(id: string): Observable<string> {
return of('foo').pipe(delay(1000));
}
getTwo(id: string): Observable<string> {
return of('bar').pipe(delay(1000));
}
getThree(id: string): Observable<string> {
return of('baz').pipe(delay(1000));
}
getFour(id: string): Observable<string> {
return of('foobar').pipe(delay(1000));
}
ngOnInit(): void {
zip(
this.getOne('foo').pipe(
switchMap(oneResult =>
this.getTwo(oneResult).pipe(
map(twoResult => ({ oneResult, twoResult }))
)
),
switchMap(oneTwoResult => {
console.log(oneTwoResult);
return this.getThree(oneTwoResult.oneResult);
})
),
this.getFour('foobar')
)
.subscribe(result => console.log(result));
}
}
Using resultSelector
function of switchMap
:
zip(
this.getOne('foo').pipe(
switchMap(oneResult =>
this.getTwo(oneResult),
(oneResult, twoResult) => ({ oneResult, twoResult })
),
switchMap(oneTwoResult => {
console.log('oneTwoResult: ', oneTwoResult);
return this.getThree(oneTwoResult.oneResult)
})
),
this.getFour('foobar')
)
.subscribe(result => console.log(result));
Here is a StackBlitz showing this functionality in action.
Hopefully that helps!
Upvotes: 3