Reputation: 13485
I am using Retrofit with Rxjava to retrieve a Single response.
@GET("/commonapi/search")
Single<MyEntity> requestAddressRx(@Query("searchVal") String searchVal,
@Query("pageNum") int pageNum);
I have a json that will return the following
{"found":240,"totalNumPages":16,"pageNum":1,"results":[...
Currently, to retrieve all 16 pages, I have to do the following: -
Is there a way where I can combine step 1 and 2 together?
//After some bumbling around - what i currently have is
Single<List<MyEntity>> result = addressRetrofitRx.requestAddressQueryRx(query, 1)
//now i get the number of pages from the results
// -NOTE: the result is now discarded :(
.map( r-> r.getTotalNumPages() )
//now i create a flowable from the number of pages
.flatMapPublisher(totalNumPages -> Flowable.range(1, totalNumPages))
.flatMapSingle(pageNumber -> addressRetrofitRx.requestAddressQueryRx(query, pageNumber))
.toList();
This causes Rxjava to call page 1 twice (the first time is read and discarded after I read the totalNumPages).
Also if the result only have 1 totalNumPages, I will still spawn the flowable.
There ought to be a better way to approach this problem, but I can't seem to figure it out. JSON schemas where the numberOfPages is encoded in the result are very common, so I assumed there's a correct RxJava way of parsing them.
Upvotes: 1
Views: 1226
Reputation: 69997
You don't have to map out the total number of pages, just concat the first page's MyEntity
with the rest of the pages:
Single<List<MyEntity>> result = api.requestAddressQueryRx(query, 1)
//now i create a flowable from the number of pages
.flatMapPublisher(r -> {
Flowable<MyEntity> pages = Flowable.just(r);
int maxPages = r.getTotalNumPages();
if (maxPages > 1) {
pages = pages
.concatWith(
Flowable.range(2, maxPages - 1)
.flatMapSingle(pageNumber ->
api.requestAddressQueryRx(query, pageNumber)
, /* eager error */ false, /* keep order of pages */ 1)
);
}
return pages;
})
.toList();
Upvotes: 1