I am using angular 2 and it's http ponent.
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.
I am using angular 2 and it's http ponent.
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.
Share Improve this question asked Jul 11, 2016 at 13:58 JNKJNK 8367 silver badges13 bronze badges2 Answers
Reset to default 6Recursion 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) // unment 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.