b_it_s
b_it_s

Reputation: 724

Angular: return value from forkJoin inside pipe of other observable

This is my scenario I need to implement:

  1. I call an API which returns a response with an array of objects
  2. I map those objects to another array of objects
  3. For each item of this new array of objects, I need to call another API call
  4. The response of the second call must set a value in each object of my array I created in 2.
  5. I want to return an observable with the array of objects from 4.

So far I've been able to create the following:

public getWishlist ( receiver : Person) : Observable<Wish[]>{
    return this.http$.get<IWishlistResponse[]>(environment.apiUrl + 'wishlist/' + receiver.id).pipe(
      map( (response) => {
        let wishes: Wish[] = [];
        response[0].wishes.forEach((wish) => {
          wishes.push(new Wish(
            wish._id,
            wish.title,
            wish.price,
            null,
            wish.url
          ));
        });
        return wishes;
      }),
      tap( (wishes) => {
        let wishStateObservables = wishes.map(wish => this.http$.get<wishStatus>(environment.apiUrl + 'wish/' + wish.id + '/state').pipe(catchError(() => of(null))));
        forkJoin(wishStateObservables)
          .pipe(
            map(states => {
              states.forEach((state, index) => {
                wishes[index].status = state;
              });
              return wishes;
            })
          ).subscribe((wishes => { console.log(wishes) }));
      })
    );

The 'wishes' in console.log in subscribe of the forkjoin are the values I want to return in my observable, but I can't get them in this observable. So what should I use instead of the 'tap' operator. to be able to put the results of the forkJoin pipe in the observable I return?

Upvotes: 0

Views: 2600

Answers (1)

AliF50
AliF50

Reputation: 18899

Try switching the tap for a switchMap which switches to a new observable.

import { switchMap } from 'rxjs/operators';
...
public getWishlist ( receiver : Person) : Observable<Wish[]>{
    return this.http$.get<IWishlistResponse[]>(environment.apiUrl + 'wishlist/' + receiver.id).pipe(
      map( (response) => {
        let wishes: Wish[] = [];
        response[0].wishes.forEach((wish) => {
          wishes.push(new Wish(
            wish._id,
            wish.title,
            wish.price,
            null,
            wish.url
          ));
        });
        return wishes;
      }),
      switchMap( (wishes) => { // change to switchMap to switch to new observable
        let wishStateObservables = wishes.map(wish => this.http$.get<wishStatus>(environment.apiUrl + 'wish/' + wish.id + '/state').pipe(catchError(() => of(null))));
        return forkJoin(wishStateObservables); // add return here to return for the switchMap
      }),
      map(states => { // remove the inner pipe from the forkJoin and put the pipe in outer pipe
              states.forEach((state, index) => {
                wishes[index].status = state;
              });
              return wishes;
      }),
    );

Upvotes: 1

Related Questions