Any Rx operator which could FlatMap and return both the output

Tags: , , , ,



I want to know if there’s an appropriate RxJava operator for my use-case. I have the below two methods. These are retrofit interfaces.

fun getSources(): Single<Sources>
fun getTopHeadlines(sourceCsv: String): Single<TopHeadlines>

Currently I’m doing this

getSources()
    .map { sources -> 
        // convert the sources list to a csv of string 
    }
    .flatMap { sourcesCsv
        getTopHeadlines(sourcesCsv)
    }
    .subsribe {topHeadlines, error -> }

This works well and good, if my objective is to get the top headlines. But what I’m instead trying to get is both the sources as well as top headlines while subscribing to it? Is there any operator that I’m not aware off or is there any other way of doing the same?

Answer

you can use the zip() method to do this. zip waits for both items then emits the required value. you can use it like this

getSources()
    .map { sources -> 
        // convert the sources list to a csv of string 
    }
    .flatMap { sourcesCsv ->
        Single.zip(
            Single.just(sourcesCsv),
            getTopHeadlines(sourcesCsv),
            BiFunction { t1, t2 -> Pair(t1, t2) }
        )
    }
    

then when you subscribe to this you have both values as a Pair. you can make an extension function for it and make you life easier:

fun <T, V> Single<T>.zipWithValue(value: V) = Single.zip(
    Single.just(value),
    this,
    { t1, t2 -> Pair(t1, t2) }
)

and inside your flatMap you can do getTopHeadlines(sourcesCsv).zipWithValue(sourcesCsv). the same could be done for Maybe, and for Flowabale you can use combineLatest() method.



Source: stackoverflow