i am migrating from rxjava to coroutines and just ...
# android
l
i am migrating from rxjava to coroutines and just stumped on something now. is there an equivalent to
Copy code
local.onErrorResumeNext { remote }
with coroutines?
g
local.catch { emitAll(remote) }
Also you can see that onErrorResumeNext exists for Flow, but it’s deprecated and provides replacement it made this way to help users who more familiar with rxjava to find Flow operators
l
i am trying to rewrite this rxjava code
so far this is what i have but i know its incomplete
g
Copy code
catch { flowOf(remote) }
You need catch { emit(remote) }
What is type of coinLocalDataSource.getCoins().? If it Flow, why you do flowOf(local)
Also what is type of coinRemoteDataSource.getCoins()? Is it just suspend function? If so, you need:
Copy code
.catch { emit(coinRemoteDataSource.getCoins()) }
It’s not good style to have suspend function which returns Flow, I believe you need it only because of getCoins, so you can just move it to catch and it will allow make function not suspend
l
yeah i am not very familiar with Flow, so that may just be a misuse
this is
coinLocalDataSource.getCoins()
Copy code
suspend fun getCoins(): List<CoinEntity> {
        return coinDao.getAllCoins()
    }
this is
coinRemoteDataSource.getCoins()
Copy code
suspend fun getCoins() : List<CoinResponse> {
        return coinService.getCoins()
    }
btw thank you so much for all of your help
g
if both of those functions are just suspend, why you even need Flow?
l
i don’t think i need Flow
g
why not rewrite it as simple suspend function:
l
yeah i would prefer to keep it simple
g
yep, looks that you just need suspend function
Copy code
suspend fun getCoins(): List<CoinResponse> {
        
          val local = coinLocalDataSource.getCoins()
          return if (local.isEmpty()) {
             coinRemoteDataSource.getCoins()
          } else {
             local
          }.map { it.toResponseModel() }
}
Only don’t forget that getCoins will not catch exceptions
l
okay that almost has everything
but what about this piece …
Copy code
val remote =
      coinRemoteDataSource.getCoins()
.doOnSuccess {  
   coinLocalDataSource.saveCoins(it.toEntityModels())
}
g
Copy code
val local = coinLocalDataSource.getCoins()
          return if (local.isEmpty()) {
             val remote = coinRemoteDataSource.getCoins()
             coinLocalDataSource.saveCoins(remote.toEntityModels())
             remote
          } else {
             local
          }.map { it.toResponseModel() }
Really, like any other non-reactive code
l
i think this is what i need
Copy code
suspend fun getCoins(): List<CoinResponse> {
        val local = coinLocalDataSource.getCoins()
        return if (local.isEmpty()) {
            val remote = coinRemoteDataSource.getCoins()
            if(remote.isNotEmpty())
                coinLocalDataSource.saveCoins(remote.toEntityModels())
            remote
        } else {
            local.toResponseModels()
        }
    }
g
yep