I'm stuck on a simple task and i'm pretty sure i'm heading the wrong way. I just need to fetch a list of items. I can only get items by 50 and I don't know the exact number of page.
So what I need to do is make the call and repeat it until I get less than 50 items (which means it's the last page), then return the complete list with an insert in a db
The api call is a single, and I need to return a single. Api call:
@GET("posts")
fun getItems(@Query("page") page: Int, @Query("per_page") perPage: Int): Single<List<Item>>
This is what I got so far:
fun getItems(): Single<List<Item>> {
var result = listOf<Item>()
return Observable.range(1, Integer.MAX_VALUE).concatMapSingle { page ->
remoteDataSource.getItems(page, 50).map {
result = it
it
}
}.repeatUntil {
result.size != 50
}.single(emptyList()).map {
localDataSource.insertItems(it)
it
}
}
The problem is I got an error when the second page is fetched: java.lang.IllegalArgumentException: Sequence contains more than one element!
How can I do to append each calls to a list and emit that list when I reached the last page? Should I change single to flowable for example?
You need takeUntil
to cut off the paging and re-accumulate all the individual pages:
Observable.range(1, Integer.MAX_VALUE)
.concatMapSingle { page ->
remoteDataSource.getItems(page, 50)
}
.takeUntil {
it.size != 50
}
.flatMapIterable { it }
.toList()