Buttars
Buttars

Reputation: 55

Transform Observable<String[]> to Observable<DataType[]>

I have an api that returns me an Array<string> of ids, given an original id (one to many). I need to make an http request on each of these ids to get back the associated data from the api. I cannot figure out how to take the Observable<string[]> and map it to the Observable<DataType[]>.

I would like to keep the original observable and use operators to get the desired outcome if at all possible.

Piping the map operator doesn't work in this situation due to the fact that the only item in the observable is the array.

Here's some example code that is similar to the implementation I am attempting.

getIds = (originalId: string) => {
 return this.http.get<string[]>(url);
}

getDataFromIds = (originalId: string): Observable<DataType[]> => {
  const ids$ = this.getIds(originalId);
  // Make http calls for each of the items in the array.
  result = ids$.pipe();

  return result;
}

Upvotes: 3

Views: 197

Answers (2)

Zdravko Tatarski
Zdravko Tatarski

Reputation: 184

You can try this:

ids$.pipe(
  switchMap(ids => //you can swap switchMap with any *Map operator: https://www.learnrxjs.io/operators/transformation/
    forkJoin(...ids.map(id => //you swap forkJoin with any comb. operator: https://www.learnrxjs.io/operators/combination/
      from(Promise.resolve({ id })).pipe(
        map(res => res.id),
        catchError(err => of(err)))))));

Imports for from, forkJoin should be from rxjs, while everything else is imported from rxjs/operators

catchError will catch any thrown unhandled errors.

Demo: https://stackblitz.com/edit/rxjs-xmmhyj

Upvotes: 0

bryan60
bryan60

Reputation: 29355

this is a use case for the switchMap operator typically, with the forkjoin operator as your inner observable.

getIds = (originalId: string) => {
 return this.http.get<string[]>(url);
}

getDataFromIds = (originalId: string): Observable<DataType[]> => {
  const ids$ = this.getIds(originalId);
  // Make http calls for each of the items in the array.
  result = ids$.pipe(switchmap(ids => forkJoin(ids.map(id => this.getId(id))));
  // map the array of ids into an array of Observable<DataType>, forkjoin them and switch into it.

  return result;
}

This is assuming the getIds() call will result in a list of string ids and that you have some getId() function that takes a string ID and returns an observable DataType

Upvotes: 3

Related Questions