How to execute another api based on first api data

Viewed 119

I am learning RxJS. I have 2 api, based on data of 1st api, I have to call second api and return the value. I did with subscribe() method like this:

checkPermission(permissionName: string): Observable<boolean> {
    this.checkCompanySettingForPermission(
      this.pageLevelCompanySettingName
    ).subscribe(res => {
      const shouldCheck = res.Value;
      if (shouldCheck.toLowerCase() === "true") {
        this.hasPermission(permissionName).subscribe(res => {
          this.$permissionSub.next(res.permission);
        });
      } else {
        this.$permissionSub.next(true);
      }
    });
    return this.$permissionSub.asObservable();
  }

I want to avoid subscribe() method in another subscribe() method. Can I do with any operator of RxJS?

I tried it with switchMap() also but getting lots of syntax error. Please help.

2 Answers

You can achieve that using one of the Higher-Order RxJS mapping operators such as: switchMap, mergeMap, concatMap, merge the source observable with the new one.

So if we go with switchMap or mergeMap in your case we should return at the end a new observable to be merged with the original one checkCompanySettingForPermission.

If the condition is true, will return the this.hasPermission observable, else will return a new observable using of function with the value we need to pass (true in your case).

You can try the following:

checkPermission(permissionName: string): Observable<boolean> {
  this.checkCompanySettingForPermission(this.pageLevelCompanySettingName)
    .pipe(
      switchMap(res => {
        const shouldCheck = res.Value;
        if (shouldCheck.toLowerCase() === 'true') {
          // switchMap to the new observable, then map it to return only the permission.
          return this.hasPermission(permissionName).pipe(
            tap(result => {
              // do some stuff with the result before mapping it to the `result.permission`
            }),
            map(result => result.permission)
          );
        } else {
          // return observable of true, to be handled within subscribe.
          return of(true);
        }
      })
    )
    .subscribe(permission => this.$permissionSub.next(permission));

  return this.$permissionSub.asObservable();
}

And if you don't use the this.$permissionSub elsewhere, you can remove it from the method above, and return this.checkCompanySettingForPermission(....) without subscribe, then you can call this method in your component like the following:

// Example
this.service.checkPermission(addPermission).subscribe((value) => {
   console.log(value)
})

Try this format.

checkPermission(permissionName: string): Observable<boolean> {
  this.checkCompanySettingForPermission(this.pageLevelCompanySettingName)
    .pipe(
      map(res => res?.Value.toLowerCase() === 'true'
          ? this.hasPermission(permissionName).pipe(
               map(result => result.permission)
            )
          : of(true)

       ),
      switchMap(ob => ob)
    )
    .subscribe(permission => this.$permissionSub.next(permission));

  return this.$permissionSub.asObservable();
}
Related