Vugar Abdullayev
Vugar Abdullayev

Reputation: 2085

Convert Promise to RxJs Observable

Can someone help to convert this promise to an RxJs observable? I want to get token from local storage and if error,it should be catched with observer that subscribed to observable. Below is existing solution with Promise:

  getToken(): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      resolve(JSON.parse(localStorage.getItem('currentUser')).token);
      reject();
    });
  }

and subscriber is :

 this.authService.getToken().then(token => {
      this.token = token;
    }).catch(() => console.log('Error! cannot get token'));

I tried to convert it to Observable with below method :

 getToken2(): Rx.Observable<number> {
    return Rx.Observable.create(obs => {
      obs.next(JSON.parse(localStorage.getItem('currentUser')).token);
       obs.error('Error! cannot get token');
    });
  }

and

  this.authService.getToken2()
  .subscribe((token) => console.log(token), (er) => console.log(er));

But the problem is that when error occurs while getting token from localstorage ,the RxJs observable does not catch it via obs.next().It is like it is resolved successfully.Whereas Promise catches it successfully via reject method.Can someone give an idea what is wrong? Thanks

Upvotes: 18

Views: 18127

Answers (2)

smoebody
smoebody

Reputation: 648

Your getToken()-Method should have some proper error-handling. Calling both resolve() and reject() is bad and could lead to unexpected behaviour. Better do something like this:

getToken(): Promise<any> {
  return new Promise<any>((resolve, reject) => {
    try {
      resolve(JSON.parse(localStorage.getItem('currentUser')).token);
    catch(err) {
      reject(err);
    }
  });
}

Having said that getToken2() should have proper error-handling as well, e.g.:

getToken2(): Rx.Observable<number> {
  return Rx.Observable.create(obs => {
    try {
      obs.next(JSON.parse(localStorage.getItem('currentUser')).token);
    catch(err) {
      obs.error(err);
    }
  });
}

Upvotes: 2

martin
martin

Reputation: 96889

You don't need to do all this, just use from():

import { from } from 'rxjs';

from(this.authService.getToken())
  ...
  .subscribe(...)

If you want to use a Promise anywhere in an Observable chain you don't even need to convert it to Observable as it happens automatically.

https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875

Apr 2019: Updated for RxJS 6

Upvotes: 28

Related Questions