RxJs Create an observable from the promise received

Im pretty new to RxJs and I would like to understand how best to work with Rx in conjunction with Promises.

What I want to create is a service in Angular that acts as an event dispatcher template and fires an event after the promise is completed. I also demand that if there are no subscribers (events), the observable will never be called. The last thing I want to say is that any subsequent subscribers to the observable will get the same result without starting another request to the server. I managed to implement my own solution here:

// ... CountryService code var COUNTRIES_LOADED = Rx.Observable .create(function (observer) { $http .get('/countries') .then(function (res) { observer.onNext(res); }, function (err) { observer.onError(err); }) .finally(function () { observer.onCompleted(); }); }) .shareReplay(); 

Now at any time when I sign up, a new β€œlistener” to subject to the observed will be pulled. Any new subscribers will receive a cache value without touching the server again.

So, inside my "consumer" (Angular directive), I would like to do something like this:

 // ... countryInput directive code: COUNTRIES_LOADED.subscribe(function (response) { // Fill in countries into scope or ctrl scope.countries = response.countries; }); 

Any future COUNTRIES_LOADED observer subscribers MUST NOT trigger a $ http request. Similarly, if the directive is never included on the page, $ http will never be called.

The solution above works, however, I do not know about the potential flaws and memory problems of this approach. Is this a valid solution? Is there a better / more suitable way to achieve this with RxJs?

Many thanks!

+6
source share
4 answers

I found the answer here (slightly differently named) rxjs using the promise only once on a subscription

So, for my example, the answer is as simple as:

 var loadCountries = function () { return $http.get('/countries'); }; var observable = Rx.Observable.defer(loadCountries).shareReplay(); 
+4
source

Use Rx.Observable.fromPromise(promise)

fromPromise:

Converts a Promises / A + compatible Promise and / or ES2015 compatible Promise or factory that returns the specified promise An observable sequence.

Example:

 var source = Rx.Observable.fromPromise(promise); var subscription = source.subscribe( function (x) { console.log('Next: %s', x); }, function (err) { console.log('Error: %s', err); }, function () { console.log('Completed'); }); 
+3
source

Have you tried using the fromPromise() API for rxjs5 ?

Check out the documentation here !

+1
source

Here is how you can use Observables. Let's say you have a method called getuser(username) .

 //Returns an observable getUser(username){ return $http.get(url) .map(res => res.json()); } 

And you can use it as below

 getUser.subscribe(res => console.log(response)); 

BUT if you want to use promises

 //Returns an Promise //Donot forget to import toPromise operator getUser(username){ return $http.get(url) .map(res => res.json()) .toPromise(); } 

And you can use it as below

 getUser.then(res => console.log(response)); 
+1
source

All Articles