``` interface Data data class Response( v...
# rx
a
Copy code
interface Data

data class Response(
        val data: List<Data>,
        val hasNextPage: Boolean,
        val nextPageId: Int?
)

fun makeRequest(nextPageId: Int): Single<Response> = TODO()

fun getData(page: Int = 0): Flowable<Data> = makeRequest(page)
        .flatMapPublisher {
            Flowable.fromIterable(it.data)
                    .concatWith(it.nextPageId?.let(::getData) ?: Flowable.empty())
        }
@ubu not sure how you want to do it without recursion though
💥 1
u
@arekolek, would it be correct to signal completion of this flowable by calling concatWith { publisher.onComplete() }?
a
what is
publisher
?
also, that’s what
concatWith(Flowable.empty())
does
u
When I use empty, it never completes. I use testObserver
Publisher is a Subscriber that we pass into
Copy code
.concatWith { publisher -> .... }
a
if it never completes, maybe there is never a last page in the
makeRequest
in your test?
when I run this:
Copy code
data class Data(val foo: Int)

data class Response(
        val data: List<Data>,
        val hasNextPage: Boolean,
        val nextPageId: Int?
)

fun makeRequest(page: Int): Single<Response> = Single.just(Response(listOf(Data(page)), page < 10, page.takeIf { it < 10 }?.plus(1)))

fun getPagesFrom(page: Int): Flowable<List<Data>> = makeRequest(page)
        .flatMapPublisher {
            Flowable.just(it.data)
                    .concatWith(it.nextPageId?.let(::getPagesFrom) ?: Flowable.empty())
        }

fun getData(): Flowable<List<Data>> = getPagesFrom(0).scan { acc, page -> acc + page }

getData()
        .doOnNext { println(it) }
        .doOnComplete { println("completed") }
        .doOnError { println("error") }
        .subscribe()
I get:
Copy code
scratch_23.kts:31 [Data(foo=0)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5), Data(foo=6)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5), Data(foo=6), Data(foo=7)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5), Data(foo=6), Data(foo=7), Data(foo=8)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5), Data(foo=6), Data(foo=7), Data(foo=8), Data(foo=9)]
scratch_23.kts:31 [Data(foo=0), Data(foo=1), Data(foo=2), Data(foo=3), Data(foo=4), Data(foo=5), Data(foo=6), Data(foo=7), Data(foo=8), Data(foo=9), Data(foo=10)]
scratch_23.kts:31 completed
u
thanks, let me check it one more time.
@arekolek, thanks. the problem was related with method concatWith { } taking other type of parameter.
a
makes sense, a different method is called when you pass the lambda (using
{ }
) than it is when you pass a flowable as first argument (using
()
)
u
@arekolek, yep, thanks a lot for your help. all tests passed. 💥
👍 1