Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I send multiple http requests with rx.js?

I am trying out rx.js and I am trying to make multiple http request. Here is the observable that I have set up to make the http request.

function httpGet(url) {
    return Observable.create(function forEach(observer) {
        var cancelled = false;
        axios.get(url).then(function(res) {
            if(!cancelled) {
                observer.onNext(res);
                observer.onCompleted();             
            }
        });

        return function dispose() {
            cancelled = true;
        }
    })
}

I am trying to make multiple http requests, but my result is more Observable's. Here is the subscribe:

var array = ['http://localhost:4444/text/88', 'http://localhost:4444/other/77'];

var source = Rx.Observable.fromArray(array).map(httpGet);

var subscription = source.subscribe(
    function (x) {
        console.log(x);
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
});

And here is my result.

AnonymousObservable { source: undefined, __subscribe: [Function: forEach] }
AnonymousObservable { source: undefined, __subscribe: [Function: forEach] }
Completed

I understand that I am getting Observable's and if I forEached through them, then I would get the result, but I am missing the proper way of transforming this into data and not an Observable. What am I doing wrong?

like image 903
jhamm Avatar asked Nov 29 '25 05:11

jhamm


1 Answers

That should do the trick:

var array = ['http://localhost:4444/text/88', 'http://localhost:4444/other/77'];

var source = Rx.Observable.fromArray(array).concatMap(httpGet);

function httpGet(url) {
  return axios.get(url);
  }
var subscription = source.subscribe(
    function (x) {
        console.log(x);
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
});

Some explanations:

  • an observable is a sequence of values. An observer is a three-pronged object which processes those values.
  • what you want is turn the array (source) into a sequence of html (obtained from fetching the urls). What you have at your disposal is :
    • a set of functions for creating observables from external sources : cf. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/categories.md, section Converting events or asynchronous patterns to observable sequences, or between Arrays and observable sequences.
    • a set of operators allowing to take those source sequences into the sequences of your making (same link than above).
  • you then want to subscribe to the produced sequences and do something with them. That is the subscribe function where you define your observer.
  • so here you take your sequence of array values, produce a sequence of promises with the map operator, BUT actually you will use the concatMap operator to output the promise resolved values in the same order than the array values. concatMap can take an observable, an array/iterable or a promise as its argument, and will output the sequence of values wrapped into those objects in the observable it returns. So instead of having a sequence of promises you have a sequence of values resolved by the promises i.e. your fetched html content. If you are not interested in keeping the initial ordering of the source, you could also use the flatMap operator. Cf. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/concatmap.md and https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/selectmany.md
  • then you subscribe to that, and process those values

So this is basically the general process, you take a source sequence, turn that into a sequence of your choice through a judicious choice of operators, and then process the values one by one with your observer function. Also, note that a promise is akin to an observable, and some (most?) Rxjs operators will treat them as such, so you often do not have to use then to get the resolved value.

Last thing, Rx.Observable.fromArray seems to be deprecated in favor of Rx.Observable.from : cf. https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromarray.md

like image 92
user3743222 Avatar answered Dec 01 '25 20:12

user3743222