Reputation: 25032
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 forEach
ed 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?
Upvotes: 3
Views: 4915
Reputation: 18665
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:
Converting events or asynchronous patterns to observable sequences, or between Arrays and observable sequences.
subscribe
function where you define your observer.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.mdSo 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
Upvotes: 12