Search code examples
androidkotlinrx-java2rx-androidrx-kotlin

RxJava2. Execute a request for every item in a list


I have a list List<FileModel>

FileModel is just a class contains id: Int

id - is ID of photo file I need to fetch and cast to Bitmap

I have a request:

fun getFile(fileId: Int): Single<ResponseBody>

This request returns ResponseBody which we can cast to Bitmap

And

fun generatePhoto(responseBody: ResponseBody): Single<Bitmap?>

What I want is to create a function

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> {
    // Execute getFile(...) for each item in the list
    // Cast getFile(...) result to Bitmap using generatePhoto(...)
    // Return a list of Bitmaps
}

I've tried something like this but it's completely wrong

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> {
    return Observable.fromIterable(list)
        .flatMap { getFile(it.id) }
        // How to call generatePhoto(...) here?
}

Solution

  • You can do it like this:

    fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> {
        // Get an Observable of the list
        return Observable.fromIterable(list)
            // Get a Single<ResponseBody> for every FileModel
            .flatMapSingle { getFile(it.id) }
            // Get a Single<Bitmap> for every ResponseBody
            .flatMapSingle { file -> generatePhoto(file) }
            // Put everything back on a list
            .toList()
    }
    

    This way you can iterate over the list flapMapping for your needs and then putting it back together as a list in the end. The toList() operator is just a convenience that puts together the items emitted previously.

    And to call this function just go:

        getPhotos(list)
            .doOnSuccess { resultList ->
              Log.d("Rx", "doOnSuccess.resultList=[$resultList]")
            }
            .subscribe()
    

    By the way, if you have RxKotlin as a dependency you can get an Observable from a List with an extension function, like this: myList.toObservable()