Search code examples
androidrx-javareactive-programmingrx-java2rx-java3

Repeat a request X number of times or till Y items is returned


I have trouble creating an Observable with the following conditions:

  1. Fetch items from API. API can return between 0 and 10 items.
  2. If less then 10 items is returned, request more items from the API.
  3. Repeat 5 times or till 10 or more items are collected.

So far I have this Observable:

fetchData().flatMapIterable { dataList }
            .distinct()
            .filter { --some filtering--- }
            .repeat(5)
            .take(10)
            .toList()

This works ok, with one nitpick. If API returns 9 items and then 10 items, the Observable returns 10 items. The remaining 9 are discarded and I don't want that. Any way to make it work that way?


Solution

  • Have it collect into a list shared across multiple steps and perform a conditional repeat:

    Single.defer {
        var list = ArrayList<T>()
        var count = AtomicInteger()
    
        fetchData()
        .flatMapIterable { dataList }
        .distinct()
        .filter { --some filtering--- }
        .collectInto(list, { list, item -> list.add(item) })
        .repeatUntil { list.size() >= 10 || count.getAndIncrement() > 4 }
        .ignoreElements()
        .andThen(Single.just(list))
    }