furry12
furry12

Reputation: 962

Chaining Observable with Promises for common error handling - Angular

I am writing writing an application using the latest version of the Angular framework. I came across a problem - some of my methods return observables, and some return promises. Is it possible to chain them in order to define a single catch block for all requests in the chain? (I mean the way you would normally do with just promises).

Take a look at this code sample:

loginToBackendServer(token: string) {
return new Promise ((resolve, reject) => {
  this.userService.loginUserWithFb().subscribe(backendUser => {
    this.facebookProvider.getBasicUserData().then(profile => {
      let userData = {
        id: backendUser['id'],
        facebookId: profile['id'],
        picture: profile['picture_large']['data']['url'],
        name: profile['name']
      };
      this.userService.userData = userData;
      this.sharedService.emitUserData(userData);
      this.storage.set("fbAccessToken", token);
      resolve();
    })
      .catch(error => {
        console.log(error);
        reject();
      })
  }, error => {
    console.log(error);
    reject();
  });
});

}

How do I chain the .subscribe() and the .then() so that I only have one catch block instead of having to handle errors separately?

Thanks guys!

Upvotes: 1

Views: 760

Answers (1)

Luillyfe
Luillyfe

Reputation: 6842

You do not need to use a new promise to chain all the response and catch the error in one point. By using fromPromise and concatMap allow you to chain and keep your code organize (Note that I am using the pipeable operators, it is highly recommend to do so).

import { fromPromise } from 'rxjs/observable/fromPromise';
import { concatMap } from 'rxjs/operators';

...

loginToBackendServer(token: string) {
      this.userService.loginUserWithFb().pipe(
          concatMap(backendUser => fromPromise(this.facebookProvider.getBasicUserData()))
      ).subscribe(profile => {
          let userData = {
              id: backendUser['id'],
              facebookId: profile['id'],
              picture: profile['picture_large']['data']['url'],
              name: profile['name']
          };

          this.userService.userData = userData;
          this.sharedService.emitUserData(userData);
          this.storage.set("fbAccessToken", token);
      }, error => {
          console.log(error);
      });
  }

Upvotes: 3

Related Questions