4

I was trying to pass events from UI to viewModel using sharedFlow this is my viewmodel class

class MainActivityViewModel () : ViewModel() {
    val actions = MutableSharedFlow<Action>()
    private val _state = MutableStateFlow<State>(State.Idle)
    val state: StateFlow<State> = _state

    init {
        viewModelScope.launch { handleIntents() }
    }

    suspend fun handleIntents() {
        actions.collect {
            when (it) {...}
       }
   }
}

and this is how i am emiting actions

private fun emitActions(action: Action) {
        lifecycleScope.launch {
        vm.actions.emit(action)
        }
    }

For the first time emission happening as expected, but then it is not emitting/collecting from the viewmodel.

Am i doing anything wrong here??

  • Hi, Welcome to StackOverflow! Can you provide a bit more context on what is happening when `emitActions()` is called for the 2nd time? Does `actions.collect()` not get called with the new value? Can you try debugging the same (set breakpoints inside `collect { }` and `emitActions()` to verify they work fine) and share the results? – Yashovardhan99 Jun 19 '21 at 19:23
  • Yes tried, but execution not reaching inside collect – noushad_chullian Jun 20 '21 at 06:30

3 Answers3

5

When I used collectLatest() instead of collect() it worked as expected

Boken
  • 4,825
  • 10
  • 32
  • 42
  • Collect cancels previous action. So when you send 0 , 1 , 2, 3. only 3 will be finished. Previous are canceled – Vetalll Sep 28 '21 at 08:54
0

collectLatest() instead of collect() hides the problem

when you do launch{ collect() } the collect will suspend whatever it is in launch code block

so if you do

launch{
  events.collect {
    otherEvent.collect() //this will suspend the launched block indefinetly
  } }

solution is to wrap every collect in it's own launch{} code block, collectLatest will just cancel the suspend if new event is emitted

Hessesian
  • 51
  • 2
0

Did you try using UnconfinedTestDispatcher()? That should fix the issue

Faustino Gagneten
  • 2,564
  • 2
  • 28
  • 54