Search code examples
kotlinkotlin-coroutineskotlin-flow

Chain kotlin flows depends on Result state


I'm looking for the most "clean" way to implement the following logic:

  • I have N methods, everyone returns Flow<Result<SOME_TYPE>> (type are different)
  • I want to chain these methods, so if 1 returns Result.Success, then call 2nd and so on.

The most obvious way to do it is:

methodA().map { methodAResult ->
  when (methodAResult) {
    is Result.Success -> {
      methodB(methodAResult).map { methodBResult ->
        when (methodBResult) {
          is Result.Success -> {
            methodC(methodAResult).map { methodCResult ->
              when (methodCResult) {
                is Result.Success -> TODO()
                is Result.Failure -> TODO()
              }
            }
          }
          is Result.Failure -> TODO()
        }
      }
     }
     is Result.Failure -> TODO()
   }
 }

But it looks like a well-known "callback hell". Do u have any ideas how to avoid it?


Solution

  • I believe this could be flattened with transform operator:

    methodA().transform { methodAResult ->
        when (methodAResult) {
            is Success -> methodB(methodAResult).collect { emit(it) }
            is Failure -> TODO()
        }
    }.transform { methodBResult ->
        when (methodBResult) {
            is Success -> methodC(methodBResult).collect { emit(it) }
            is Failure -> TODO()
        }
    }.transform { methodCResult ->
        when (methodCResult) {
            is Success -> TODO()
            is Failure -> TODO()
        }
    }