Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 560
Vugar Abdullayev Avatar asked Sep 11 '17 09:09

Vugar Abdullayev


People also ask

Can I convert Promise to Observable?

To convert a promise to an observable with Rxjs, we can use the from function. import { from } from "rxjs"; //... const observable = from(promise);

Can we convert RXJS Observable into a Promise?

RxJS allows to turn any Observable into a Promise with the firstValueFrom function (note: since RxJS 7, toPromise is deprecated): const obs = of(1); const promise = firstValueFrom(obs);

How do you make an Observable Promise?

How to Convert an Observable to a Promise in Angular? Since the get method of HttpClient returns an observable, we use the toPromise() method to convert the observable to a promise. Since you can convert an observable to a promise, you can make use of the async/await syntax in your Angular code.

How do you use Observable instead of Promise?

The biggest difference is that Promises won't change their value once they have been fulfilled. They can only emit (reject, resolve) a single value. On the other hand, observables can emit multiple results. The subscriber will be receiving results until the observer is completed or unsubscribed from.


2 Answers

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

like image 106
martin Avatar answered Oct 30 '22 03:10

martin


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);
    }
  });
}
like image 34
smoebody Avatar answered Oct 30 '22 03:10

smoebody