I have 5 different URLs that each return data in the from of an array of objects. I want to concat these objects into a single array that I store local to my ANgular2 componenent. Right now, I do something like this in my ngOnInit:
this.myHttpService.graburl1data()
.subscribe(
response => {
if(!this.mylist) {
this.mylist = []
this.mylist = this.mylist.concat(response);
} else {
this.mylist = this.mylist.concat(response);
}
this.myHttpService.graburl2data()
.subscribe(
response => {
if(!this.mylist) {
this.mylist = []
this.mylist = this.mylist.concat(response);
} else {
this.mylist = this.mylist.concat(response);
}
});
});
There has to be a better way, please help!
Suppose you have two requests and each returns an observable that emits an array as a stream value:
const response1 = of([1, 2, 3]);
const response2 = of([4, 5, 6]);
You want to get those values as a stream of values - flattened. You can use a combination of operators to do that:
const merged = merge(response1, response2).mergeMap((a) => {
return a;
});
merged.subscribe((v) => {
console.log(v);
});
You will get the following output:
1
2
3
4
5
6
In your case you will obtains the response
observables by calling the http
:
const response1 = this.myHttpService.graburl1data(),
const response2 = this.myHttpService.graburl2data()
...
So, the final code is:
import { merge } from 'rxjs/observable/merge';
import 'rxjs/add/operator/mergeMap';
const merged = merge(
this.myHttpService.graburl1data(),
this.myHttpService.graburl2data()
).mergeMap((a) => {
return a;
});
merged.subscribe((v) => {
console.log(v);
});
Your snippet seems to suggest that there is no dependency between the requests, so you can use forkJoin
to peform them in parallel:
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/forkJoin";
Observable.forkJoin(
this.myHttpService.graburl1data(),
this.myHttpService.graburl2data()
)
.subscribe(
(responses) => {
// ... responses[0] is the response from this.myHttpService.graburl1data
// ... etc.
}
);
responses
will be an array of the responses in the order in which the request observables were passed to forkJoin
.
If you want the requests performed in series, use concat
and toArray
instead:
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/concat";
import "rxjs/add/operator/toArray";
Observable.concat(
this.myHttpService.graburl1data(),
this.myHttpService.graburl2data()
)
.toArray()
.subscribe(
(responses) => {
// ... responses[0] is the response from this.myHttpService.graburl1data
// ... etc.
}
);