Reputation: 665
I have a service that returns an Observable containing a collection of objects. The initial web call returns a collection, however within the collection of items, I need to make a supplementary call to retrieve some extra data. The result should be a new object which is generated using the two responses.
The code looks a bit like this:
let result: Array<InvitationModel> = new Array<InvitationModel>();
this.apiService.getInvitations().map((invitations : Array<InvitationResponse>) => {
invitations.forEach(inv => {
this.apiService.getInvitationData(inv).map((data: DataResponse) => {
result.push(new InvitationModel(inv, data));
});
});
return result;
This doesn't work, which I understand, but I'm not sure of the correct way to write it so that I can only return result once the loop has completed.
Any advice would be appreciated.
Upvotes: 1
Views: 800
Reputation: 3253
What you are looking for is the Rxjs.Observable.switchMap metho (https://www.learnrxjs.io/operators/transformation/switchmap.html) With this method you will wait until all the observables in the switchmap block are resolved (you basically switch to a new observable). Also the way with the result array won't work since the observable part is executed async, that means you should return an observable from your function and subscribe on the outside to retrieve the data
Your example could look something like this:
return this.apiService.getInvitations().switchMap((invitations: Array<InvitationResponse>) => {
let result: Array<InvitationModel> = new Array<InvitationModel>();
return Observable.forkJoin(...invitations.map(inv => {
this.apiService.getInvitationData(inv).map((data: DataResponse) => {
result.push(new InvitationModel(inv, data));
});
})).map(() => {
return result;
});
});
Quick explanation:
As I said above with the .switchMap
you are waiting until your child observables are resolved
With invitations.map(inv => {
you create an array with observables for your child operation.
With Observable.forkJoin(
you combine all the observables from the array to a single one to wait for.
Upvotes: 4