Kaki6876
Kaki6876

Reputation: 87

What operator is used to get several values from observable

   return this.usersTableService.fetchRequestedPageUsersIds(request).pipe(
        switchMap((idsToFetch) => {
          requestedIds = idsToFetch;
          return [this.usersTableService.getNewIdsToFetch(requestedIds, entities), of(idsToFetch)];
        }),
        //.......?(([newIds, idsToFetch]) => {
          return this._fetchNewUsersFromAPI(requestedIds, request, newIds, entities);
        }),
        catchError((err) => of(loadPageFail(err)))
      );

what operator should I use in order to get the value of the return tuple before ?

Upvotes: 0

Views: 70

Answers (2)

Ajantha Bandara
Ajantha Bandara

Reputation: 1531

You can use forkJoin for this

 return this.usersTableService.fetchRequestedPageUsersIds(request).pipe(
        switchMap((idsToFetch) => {
          return forkJoin([this.usersTableService.getNewIdsToFetch(requestedIds, entities), of(idsToFetch)]);
        }),
        mergeMap(([newIds, idsToFetch]) => {
          return this._fetchNewUsersFromAPI(requestedIds, request, newIds, entities);
        }),
        catchError((err) => of(loadPageFail(err)))
      )

Upvotes: 2

wlf
wlf

Reputation: 3403

You would normally use the map operator(https://stackblitz.com/edit/so-tuple-map?file=index.ts):

const obs$ = of(1).pipe(map(y => ['abc', 'def']), map(([str1, str2]) => str1 + str2))

But if you try that you will encounter other issues with your code ie:

  • its not good practice to store a local variable inside a switchMap then return it using of
  • _fetchNewUsersFromAPI needs to be inside a switchMap

Ultimately you'll still be faced with the fundamental problem of how to pass parameters down the observable chain, which I suspect is how you've ended up in this situation to begin with.

There is currently a bountied question asking about the same problem here: How to pass results between chained observables

IMO the best solution from that question is to use nested pipes ie:

const newUsers$ = requestsSubject.pipe(
  switchMap(request =>
    this.usersTableService.fetchRequestedPageUsersIds(request).pipe(
      switchMap(idsToFetch =>
        this.usersTableService.getNewIdsToFetch(idsToFetch).pipe(
          switchMap(newIds =>
            this._fetchNewUsersFromAPI(idsToFetch, request, newIds, entities)
          )
        )
      )
    )
  )
);

An alternative way using await and toPromise:

function getUsers(request){
  const idsToFetch = await this.usersTableService.fetchRequestedPageUsersIds(request).toPromise();
  const newIds = await this.usersTableService.getNewIdsToFetch(idsToFetch, entities).toPromise();
  const newUsers = await this._fetchNewUsersFromAPI(idsToFetch, request, newIds, entities).toPromise();
  
  return newUsers;
}

Upvotes: 1

Related Questions