简体   繁体   中英

Coroutine StateFlow.collect{} not firing

I'm seeing some odd behavior. I have a simple StateFlow<Boolean> in my ViewModel that is not being collected in the fragment. Definition:

private val _primaryButtonClicked = MutableStateFlow(false)
val primaryButtonClicked: StateFlow<Boolean> = _primaryButtonClicked

and here is where I set the value:

fun primaryButtonClick() {
    _primaryButtonClicked.value = true
}

Here is where I'm collecting it.

     repeatOnOwnerLifecycle {
        launch(dispatchProvider.io()) {
            freeSimPurchaseFragmentViewModel.primaryButtonClicked.collect {
                if (it) {
                    autoCompletePlacesStateFlowModel.validateErrors()
                    formValidated = autoCompletePlacesStateFlowModel.validateAddress()
                    if (formValidated) {
                        freeSimPurchaseFragmentViewModel
                            .sumbitForm(autoCompletePlacesStateFlowModel.getStateFlowCopy())
                    }
                }
            }
        }
     }

repeatOnOwnerLifecycle :

inline fun Fragment.repeatOnOwnerLifecycle(
    state: Lifecycle.State = Lifecycle.State.RESUMED,
    crossinline block: suspend CoroutineScope.() -> Unit
) {
    viewLifecycleOwner.lifecycleScope.launch {
     repeatOnLifecycle(state) {
        block()
   }
}

What am I doing wrong? The collector never fires.

Does this make sense?

val primaryButtonClicked: StateFlow<Boolean> = _primaryButtonClicked.asStateFlow() 

Also I couldn't understand the inline function part, because under the hood seems you wrote something like this

viewLifecycleOwner.lifecycleScope.launch {
   viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
      launch(dispatchProvider.io()) {
        freeSimPurchaseFragmentViewModel.primaryButtonClicked.collect {
            if (it) {
                autoCompletePlacesStateFlowModel.validateErrors()
                formValidated = autoCompletePlacesStateFlowModel.validateAddress()
                if (formValidated) {
                    freeSimPurchaseFragmentViewModel
                        .sumbitForm(autoCompletePlacesStateFlowModel.getStateFlowCopy())
                }
            }
        }
     }
   }
}

Why are you launching one coroutine in another and collect the flow from IO dispatcher? You need to collect the values from the main dispatcher.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM