mars8
mars8

Reputation: 1246

Emit Flow via another suspend function in Kotlin

How can I have the flow collector below receive "hello"? The collector is calling myFunction1() which in turn calls myFunction2(). Both are suspend functions.

Currently nothing happens when I hit run and no flow is received. Am I missing something here?

CoroutineScope(IO).launch {
    val flowCollector = repo.myFunction1()
        .onEach { string ->
            Log.d("flow received: ", string)
        }
        .launchIn(GlobalScope)
}

class Repo {

    suspend fun myFunction1(): Flow<String> = flow {
        /*some code*/
        myFunction2()
    }

    suspend fun myFunction2(): Flow<String> = flow {
        /*some code*/
        emit("hello")
    }
}

Upvotes: 0

Views: 4336

Answers (2)

Sergio
Sergio

Reputation: 30705

You can try to use emitAll function for your case:

fun myFunction1(): Flow<String> = flow {
    /*some code*/
    emitAll(myFunction2())
}

fun myFunction2(): Flow<String> = flow {
    /*some code*/
    emit("hello")
}

emitAll function collects all the values from the Flow, created by myFunction2() function and emits them to the collector.

And there is no reason to set a suspend modifier before each function, flow builder isn't suspend.

Upvotes: 6

Some random IT boy
Some random IT boy

Reputation: 8467

Unless you have a very specific reason the functions returning a Flow from your repo shouldn't be suspending (As the flow{} builder isn't suspending). Since the suspending operation is collecting (waiting for values to come out of it).

From the code you've provided you're looking for the flatMapLatest function. Docs here

class Repo {

  fun function1() = 
    flow {
      val value = doSomething()
      emit(value)
    }
    .flatMapLatest { emittedValue -> function2() }
  fun function2() = flow {...}
}

Upvotes: 1

Related Questions