I want to call two observables with the second called after the first one.
I have one observable that is subscribed too first. Then I want the second observable nested within the first observable.
I want to combine these two subscribes below:
this.serviceA.getData()
.takeUntil(destroyed$)
.subscribe(item => {
});
this.serviceB.getData()
.takeUntil(destroyed$)
.subscribe(item => {
});
This is my attempt showing what I want to do (Updated)
destroyed$: Subject<any> = new Subject<any>();
ngOnInit(): void {
this.serviceA.getData
.takeUntil(this.destroyed$)
.concatMap(dataA => {
this.myDataA= dataA;
return this.serviceB.getData;
})
.takeUntil(this.destroyed$)
.subscribe(dataB => {
this.myDataA.forEach(item => {
item.visible = dataB.find(o => o.id === item.label).isVisible;
});
});
};
ngOnDestroy(): void {
this.destroyed$.next(true);
this.destroyed$.complete();
};
The aim is to have the nested subscribe called second after the first subscribe because the data is needed from the first subscriber in the second subscribe
The accepted answer is incorrect. The forkJoin
will subscribe to both Observables at the same time while you want to first subscribe to the first one and after it completes subscribe to the second one.
This is typically done using the concatMap
operator:
this.serviceA.getData()
.concatMap(response => this.serviceB.getData())
.subscribe(...)
If you want to combine the two responses use can use map
after serviceB.getData()
.
this.serviceA.getData()
.concatMap(responseA => this.serviceB.getData()
.map(responseB => /* combine responseA and responseB */ ))
.subscribe(...)
Good Question (Y),
You need to use forkJoin
docs
Runs all observable sequences in (parallel) and collect their last elements.
Example:
let character = this.http.get('https://swapi.co/api/people/1').map(res => res.json());
let characterHomeworld = this.http.get('http://swapi.co/api/planets/1').map(res => res.json());
Observable.forkJoin([character, characterHomeworld]).subscribe(results => {
// results[0] is our character
// results[1] is our character homeworld
results[0].homeworld = results[1];
this.loadedCharacter = results[0];
});
Refrence: https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs
So for your specific case you can do something like:
let obs1 = this.serviceA.getData()
let obs2 = this.serviceB.getData()
Observable.forkJoin([obs1, obs2]).subscribe(results => {
// results[0] is our obs1
// results[1] is our obs2
// show the bigger array
this.items = results[0] > results[1] ? results[0] : results[1]
});
But if you need some data dependent on the other you can do something like
showData() {
let firstData;
this.serviceA.getData()
.map((firstNeededData) => {
firstData = firstNeededData
return this.serviceB.getData()
})
.subscribe(secondNeededData => {
// I need to show the bigger
this.theBigger = secondNeededData > firstData ? secondNeededData : firstData
})
}
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