I have a Workspace model, a Request model... and now a CatalogItem model which needs to combine the two like this:
{
workspace: Workspace
requests: Request[]
}
I'm having a bit of difficulty with how I should create this with a getCatalog(): Observable<CatalogItem[]> function... which should return a CatalogItem for each Workspace, with any associated Request added to it.
I realize my attempt is way off, but I'm hoping it's enough to help understand my intent:
getCatalog(): Observable<CatalogItem[]> {
return this.http.get<Workspace[]>(`${this.baseUrl}/workspace`).pipe(
switchMap( (ws) => {
return {
workspace: ws,
requests: this.http.get<Request[]>(`${this.baseUrl}/${ws.id}/requests`).subscribe();
}
})
);
//TODO: combine workspace and request create catalog obj
}
Looking at your code, it seems like you need to call http.get<Request[]> for each workspace.
Here's how to implement it, simply follow the 3 steps below.
1.
First use mergeAll to convert Obsevable<Workspace[]> (returned by get<Workspace[]>) into a stream (so we can handle one workspace at a time).
2.
Next use mergeMap to convert each Observable<Workspace> into Observable<CatalogItem> by calling http.get<Request[]> and forming a new CtalogItem once response arrived using map (utilizing closure to reference workspace).
3.
Finally convert the stream back into array using toArray.
getCatalog(): Observable<CatalogItem[]> {
return this.http.get<Workspace[]>(`URL/workspace`).pipe(
// 1
mergeAll(),
// 2
mergeMap(workspace => this.http.get<Request[]>(`URL/${workspace.id}`).pipe(
map(requests => ({ workspace, requests })))
),
// 3
toArray()
)
}
mergeAll can flattens an Observable containing an array into a stream, for further explanation refer to @Martin's post about the best way to “flatten” an array inside an RxJS Observable
toArray collects all source emissions and emits them as an array when the source completes.
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