How to return observable in observable map in Angular

Viewed 7003

I can really find no words for what I want to do. So I just show my attempt..This is what I tried:

register(): Observable<boolean> {

   return this.registerNew().pipe(
     map(userData => {
       return this.updateProfile().pipe(                   (*1)
         map(profileData => {
           return profileData ? true : false;
         }))
     }))
}

But of course I get the following error message:

Type 'Observable<false | Observable<boolean>>' is not assignable to type 'Observable<boolean>'.

I am also thinking about using await instead of return in the line which I marked with (*1).

But still I can't get it to work in a nice way.

4 Answers

If you want to switch from one observable to another and use the value from the previous there is a switchMap operator which can be used like that

register(): Observable<boolean> {
  return this.registerNew().pipe(
    switchMap(userData => {
      return this.updateProfile().pipe(
        map(profileData => {
          return profileData ? true : false;
        }))
     }));
}

What causes to happen registerNew, then it passes resulting value to the switchMap returning observable (switchMap has to return an observable to work) and then the result of the inner observable (updateProfile) comes to subscriber.

If you want to map values of your observable to another observable, you want to use mergeMap, switchMap, or concatMap (depending on how you want the values of the newly created observable to be emitted).

await is not for Observables, only Promises.

You use the switchMapTo() operator when you don't need the emitted value, and just want to switch to another observable.

register(): Observable<boolean> {
   return this.registerNew().pipe(
     switchMapTo(this.updateProfile()),
     map(Boolean)
   );
}

You need concatMap.

  1. this example calls for the user id first, only when it has returned
  2. the second "observable" uses the returned value from the first to make the user query
this.authenticationService.currentUser.pipe(
    concatMap((principal: Principal) => this.getUser(principal.id))
).subscribe((user: User) => {
    console.log(user); // the user
});
Related