I have 5 different API calls to make, and they all are chained right now in forkJoin. My new requirement is the subscribe should fire anytime any new observable solves.
Is there any operator or any other trick in rxjs where I can keep the chaining but, it should fire each time any observable solves?
forkJoin(
this.myService.api1(),
this.myService.api2(),
this.myService.api3(),
this.myService.api4(),
this.myService.api5()
)
.subscribe(
([r1,r2,r3,r4,r5]) => { ... do something })
forkJoin Improvements This is one of my favorites. The forkJoin observable now takes a dictionary of sources: Moreover, there is one deprecation — forkJoin(a, b, c, d) should no longer be used; Instead, pass an array such as forkJoin([a, b, c, d]) .
If no input observables are provided (e.g. an empty array is passed), then the resulting stream will complete immediately. forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables.
forkJoin is one of the most popular combination operators due to its similar behavior to Promise. all but for observables. forkJoin accepts a variable number of observables and subscribes to them in parallel.
The RxJS forkJoin() operator is a join operator that accepts an Array of ObservableInput or a dictionary Object of ObservableInput and returns an Observableand then waits for the Observables to complete and then combine last values they emitted.
You can use combineLatest
to emit the latest value from each source observable. It won't emit until each source observable emits at least once, so you can use startWith
to provide a starting value:
combineLatest(
this.myService.api1().pipe(startWith(null)),
this.myService.api2().pipe(startWith(null)),
this.myService.api3().pipe(startWith(null)),
this.myService.api4().pipe(startWith(null)),
this.myService.api5().pipe(startWith(null))
)
.subscribe(
([r1,r2,r3,r4,r5]) => { ... do something })
The initial output will be [null, null, null, null, null]
. When each observable emits, it will replace the corresponding null
value in the array.
If you want to ignore the initial emission, you can use skip(1)
.
const sourceOne = of('Hello').pipe(delay(1000));
const sourceTwo = of('World!').pipe(delay(2000));
const sourceThree = of('Goodbye').pipe(delay(3000));
const sourceFour = of('World!').pipe(delay(4000));
//wait until all observables have emitted a value then emit all as an array
const example = combineLatest(
sourceOne.pipe(startWith(null)),
sourceTwo.pipe(startWith(null)),
sourceThree.pipe(startWith(null)),
sourceFour.pipe(startWith(null))
)
.pipe(skip(1));
//output:
//["Hello", null, null, null]
//["Hello", "World!", null null]
//["Hello", "World!", "Goodbye", null]
//["Hello", "World!", "Goodbye", "World!"]
//Complete
const subscribe = example.subscribe(val => console.log(val), null, () => console.log('Complete'));
And here's a StackBlitz to try it out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With