Using RxJs to generate an Observable from a Promise output

As someone who is relatively new to RxJs, I am looking to understand the most effective way to utilize Rx in conjunction with Promises.

I aim to create a service in Angular that functions similarly to an event dispatcher pattern, emitting an event once a promise is fulfilled. What I specifically need is for the observable to only be called if there are active subscribers to the event. Furthermore, I want subsequent subscribers to receive the same result without triggering additional requests to the server. I have successfully implemented my own solution as shown below:

// ... 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();

When a new "listener" subscribes to the subject, the observable will fetch the data. Subsequent subscribers will receive the cached value without contacting the server again.

In my "consumer" (Angular Directive), I envision doing something like this:

// ... countryInput directive code:

COUNTRIES_LOADED.subscribe(function (response) {
    // Populate countries into scope or ctrl
    scope.countries = response.countries;
});

Any future subscribers to the COUNTRIES_LOADED observer must not trigger an additional $http request. Similarly, if the directive is missing from the page, $http should not be contacted at all.

While the above solution works, I am unsure of any potential drawbacks and memory implications this approach may have. Is this a valid method? Is there a better or more appropriate way to achieve this using RxJs?

Thank you very much!

Answer №1

Utilize

Rx.Observable.fromPromise(promise)

fromPromise:

Converting a Promise that follows the Promises/A+ spec or an ES2015 compliant Promise, or even a function that returns such a Promise, into 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');
  });

update

The method in rxjs6 is from

Answer №2

latest information

Now with the release of rxjs6, you have the option to utilize from()


Have you experimented with using the fromPromise() functionality in rxjs5?

Review its details in the documentation found here!

Answer №3

I stumbled upon the solution here (Just with a slight variation in name) rxjs using promise only once on subscribe

For my specific case, the answer turned out to be quite straightforward:

var fetchData = function () { return $http.get('/data'); };

var stream = Rx.Observable.defer(fetchData).shareReplay();

Answer №4

Here is a guide on how to utilize Observables effectively Suppose you have a function named fetchUser(username).

//Returning an Observable
fetchUser(username){
    return $http.get(apiUrl)
        .map(response => response.json());
}

You can use it in the following manner

fetchUser.subscribe(response => console.log(response));

However, if you prefer using promises

//Returning a Promise
//Make sure to import the toPromise operator
fetchUser(username){
    return $http.get(apiUrl)
        .map(response => response.json())
        .toPromise();
}

You can then use it like this

fetchUser.then(response => console.log(response));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I utilize a callback in TypeScript when working with interfaces?

Can someone guide me on how to implement an interface in typescript with callback function? interface LoginCallback{ Error: boolean, UserInfo: { Id: string, OrganizationId: string } } interface IntegrationInterface { Ini ...

During the MEAN tutorial, I encountered an issue where inline HTML was no longer working once the 'resolve' function was added to the $stateProvider state

Currently, I am following a MEAN stack tutorial that aims to create a basic Reddit-like clone. The main page displays all posts, and each post has its separate page showing the post and comments. Everything was going smoothly until I added the resolve pro ...

Discover the nodes with the highest connections in a D3 Force Graph

As I explore the functionalities of a D3 Force Directed Graph with zoom and pan features, I encounter an issue due to my limited knowledge of d3.js. Is there a way to estimate the number of links for each node in this scenario? I am currently at a loss on ...

Obtain a picture from mongodb utilizing gridfs and display it in Ember.js

Working with Ember JS and Sails JS has been smooth sailing when uploading images to a Mongo db using the "gridfs" adapter. The chunks and files records update seamlessly, but now I've hit a roadblock. The issue arises when trying to retrieve the uplo ...

Transformation of visuals with alteration of status

I am attempting to change the image of a door from closed to open when the status changes in my home automation dashboard. I need help with this task. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&qu ...

Retrieve data from an Observable containing JSON objects

I am currently working with a Http request that returns Json data, which I then store in an observable. { "proyecto":{ "nombre": "Mercado de Ideas", "tecnologias": [ { "nombre": ".NET", "icono": "http://getsetwebsit ...

What is the method to switch between radio buttons on a webpage?

Here is an example of HTML code: <input type="radio" name="rad" id="Radio0" checked="checked" /> <input type="radio" name="rad" id="Radio1" /> <input type="radio" name="rad" id="Radio2" /> <input type="radio" name="rad" id="Radio4" /& ...

Retrieve data from REST call to populate Material dropdown menu

I am looking to dynamically populate a dropdown menu with data retrieved from a Rest API. I attempted the following code: <Select id="country-helper"> {array.map((element) => ( <MenuItem value={element.code}>{element.country}& ...

Using a JSON array, you can perform JavaScript replacements in a string by utilizing regular expressions

In order to replace all instances within {} with the corresponding data from a JSON array, I need to use a regex pattern that is case-sensitive. The number of placeholders enclosed in {}s may vary depending on the page. s ="<address><div>{Nam ...

Encoding data in an attribute using encodeURIComponent() vs using JSON.stringify()

When attempting to use an array as a data attribute, many StackOverflow answers recommend using JSON.stringify(); How to pass an array into jQuery .data() attribute Store and use an array using the HTML data tag and jQuery https://gist.github.com/charlie ...

Switch the watch feature on and off using AngularJS

Is it possible to easily turn a watch on or off, or indicate whether the watch should be active right now? I am aware that I can unregister a watch, but how do I register it again? In my scenario, I have hierarchical select lists where changing the parent ...

Struggling to unlock the mystery of a jammed trigger box

I'm currently working on implementing a small 'trigger box' that will expand upon clicking. It was functional before, but it seems to be encountering an issue now and I'm unsure of the cause. While I have some understanding of HTML and ...

VueJS allows you to trigger a Bootstrap modal using pure Javascript, eliminating the need for jQuery

I am currently developing an application with Vue.js. In the login process of my application, I want to display any potential errors using a Bootstrap modal instead of the traditional alert. Is there a method to trigger the modal using JavaScript without r ...

Using a function from one class within another class by passing it as a prop

Below are the methods found in my Search.tsx class. renderSuggestion(suggestion) { <div className="buttons"> <button className="button">View Location</button> <button className="button whitebutton" onClick={this.h ...

What is the best way to trigger a unique modal dialog for every element that is clicked on?

I simply want to click on the state and have that state's specific pop-up appear. $("path, circle").on('click', function(e) { $('#info-box').css('display', 'block'); $('#info-box').html($(this ...

Managing user input changes for API requests in ReactJS

I'm new to React and JavaScript in general, and I'm trying to retrieve country-specific data based on button clicks (updating the API URL accordingly). The buttons are functioning, but I can see in the console that the component is being called r ...

Error encountered: Multer TypeError - fields does not have a function called forEach

I'm currently working on a metadata reader using multer in node.js with express on c9. I've spent some time searching for solutions to my issue, but it seems like no one else has encountered the error I am facing: TypeError: fields.forEach is no ...

Retrieving the result of a callback function within a nested function

I'm struggling with a function that needs to return a value. The value is located inside a callback function within the downloadOrders function. The problem I'm encountering is that "go" (logged in the post request) appears before "close" (logged ...

Unable to show pop-up upon clicking

My goal is to create a popup that appears when the 'Propose' button is clicked. TestPopUp.tsx const TestPopUp = () => { return ( <div> <p>TEST</p> </div> ); }; export default TestPopUp; CandidateActi ...

Sending a large number of values unrestrictedly via ajax

I'm currently working on implementing a filter for the Google Maps API on our website. This filter will allow users to display information related to specific locations that they select by checking corresponding checkboxes. As I am still relatively ne ...