I am using angular 2 and it's http component.
I want to call a REST API that will return a list of Elements. The size of that list is limited to 100 entries. If there are more items a hasMore
flag will be set in the response. You then have to call the API again with the parameter page=2. It would be nice to have one Observable, with both server responses.
My code looks something like this:
call({page: 1})
.map(res => res.json())
.do((res) => {
if(res.meta.hasMore){
// do another request with page = 2
}
}
.map(...)
.subscribe(callback)
call
is a function that will use the http module to make the request and return an Observable. Inside of the if statement I want to make another http request and put the result on the same Observable, so that the callback, registered with subscribe, will be called twice (one time for each response).
I am not really sure how to do it. I tried using flatMap to make the next request, but had no success.
Recursion is exactly what the expand operator is for:
let callAndMap = (pageNo) => call({page: pageNo}).map(res => {page: pageNo, data: res.json()}); // map, and save the page number for recursion later.
callAndMap(1)
.expand(obj => (obj.data.meta.hasMore ? callAndMap(obj.page + 1) : Observable.empty()))
//.map(obj => obj.data) // uncomment this line if you need to map back to original response json
.subscribe(callback);
You could leverage the flatMap
operator for this:
call({page: 1})
.map(res => res.json())
.flatMap((res) => {
if(res.meta.hasMore){
return Observable.forkJoin([
Observable.of(res),
call({page: 2}).map(res => res.json()
]);
} else {
return Observable.of(res);
}
})
.map(data => {
// if data is an array, it contains both responses of request
// data[0] -> data for first page
// data[1] -> data for second page
// if data is an object, it contains the result of the first page
})
.subscribe(callback);
The last map
operator is to format the data in both cases for the callback specified in the subscribe
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With