3
votes

So I'm trying to wrap my head around Observables, and for the most part they make sense - but all the docs assume you're actually working with a stream of data - and Angular makes every http call default to an observable, even though these are not streams, but isolate values returned, which is causing some confusion for me.

So, I'm making an http call, which returns an array of objects. I then need to map over that array, and spawn a new http call based on a key within each object. Then I need to collect all the responses from those calls, and map over the initial array to set a property based on the responses from that second array of calls.

Excuse the Sudo Code

this._http.get<>(url).subscribe(value => myData = value);

which returns an array like

[
{ clientId: 1, ..additional properties},
{ clientId: 2, ..additional properties},
]

Then I need to map over this and spawn new http calls like so

response.map(item => {
 this._http.get(`someurl/${item.clientId})
}

Then I need to combine all of those calls into a single block of data, so that I can do something like

myData.map(item => {
item.fullClient = ArrayOfClientReturns.find(client => client.id === item.clientId);
}

My problem is I totally understand how to do this with promises, but with observables, I am really not sure. I understand how to use pipe(map()) to combine observables, but I don't understand how to map over an array of data and spawn a collection of observables BASED ON the response of the initial observable, then wait for them all to resolve, then re-map over the initial data set like this.

I'm sure I'm just missing the correct method in the rxjs docs, but every example shows combining observables that already exist before you try to combine them.

If someone could point me in the correct direction I'd be thankful.

1

1 Answers

7
votes

You're absolutely on the right path, you should be able to make use of something like forkJoin, which will join an array of Observables

 this._http.get<any[]>(url).pipe(
        mergeMap(arr => forkJoin(arr.map((item) => this._http.get(`someurl/${item.clientId}`).pipe(map((name) => {
           item.name = name;
           return item;
        })
 ))))

Here, we use the array map function to convert the array of objects into an array of Observables. We then use forkJoin to combine the array of observables into one, and we use mergeMap to join it to the original request.

(Please note this is using the new rxjs syntax, with pipe, but it can be done with the older syntax as well)