Как сделать один метод Rx из двух, используя flatMap?

#android #rx-java #rx-java2

#Android #rx-java #rx-java2

Вопрос:

У меня есть класс данных:

 data class MediaDetail(
val dateCreated:String,
val nasaId:String,
val keywords:List<String>,
val mediaType:String,
val center:String,
val title:String,
val description:String,
val location:String,
var assets:Map<String,String>?)
 

Мне нужно инициализировать его дважды. Первый метод fetchMediaDetails() инициализирует все поля val и активы полей var значением null. Второй метод fetchMediaAsset() инициализирует поле активов по значению.

В результате я получаю этот запрос Rx. Можно ли это сделать одним способом, используя flatMap? Если да, то как?

   fun fetchMediaDetails(nasaId:String){
    _networkState.postValue(NetworkState.LOADING)

    try {
        compositeDisposable.add(
        apiService.mediaInfo(nasaId)
            .observeOn(Schedulers.io())
            .subscribeOn(Schedulers.io())
            .subscribe ({
            fetchMediaAsset(it.item)
            },{
                _networkState.postValue(NetworkState.ERROR)
                Log.e("MediaDetailsDataSource", it.message.toString())
            })
        )
    }
    catch (e: Exception){
        Log.e("MediaDetailsDataSource", e.message.toString())
    }
}

private fun fetchMediaAsset(mediaDetail: MediaDetail){
    try {
        compositeDisposable.add(
            apiService.mediaAsset(mediaDetail.nasaId)
                .observeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .subscribe({
                    mediaDetail.assets = it.item
                    _downloadedMediaDetailsResponse.postValue(mediaDetail)
                    _networkState.postValue(NetworkState.LOADED)
                }, {
                    Log.e("MediaDetailsDataSource", it.message.toString())
                })
        )
    }
    catch (e: Exception){
        Log.e("MediaDetailsDataSource", e.message.toString())
    }
}
 

Комментарии:

1. Рекомендуемое чтение: github.com/ReactiveX/RxJava#dependent-sub-flows

Ответ №1:

Вы можете сделать это таким образом:

 fun fetchMediaDetails(nasaId:String){
    _networkState.postValue(NetworkState.LOADING)
        compositeDisposable.add(
        apiService.mediaInfo(nasaId)
            .subscribeOn(Schedulers.io())
            .flatMap { mediaDetail ->
               apiService.mediaAsset(mediaDetail.nasaId)
                         .map { assets ->
                            mediaDetail.assets = assets.item
                         }
            }
            .subscribe ({ mediaDetail -> 
                    _downloadedMediaDetailsResponse.postValue(mediaDetail)
                    _networkState.postValue(NetworkState.LOADED)
            },{
                _networkState.postValue(NetworkState.ERROR)
                Log.e("MediaDetailsDataSource", it.message.toString())
            })
        )
}