AmrJyniat

    AmrJyniat

    10 months ago
    How to call a Composable fun from coroutine while collecting a flow? compiler said you can't use Composable fun from another non Composable fun.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    10 months ago
    You can’t. As for why, consider what it would mean for a composable called from a suspend fun to emit?
    Probably you need to update some
    MutableState
    from your coroutine, and then in your composable branch on that state
    AmrJyniat

    AmrJyniat

    10 months ago
    I collect actions of the fragment in one non-composable fun, so one action need to call a composable fun. maybe I need to call the collecting fun from composable.
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    10 months ago
    Composable functions emit nodes like UI. That UI has to have somewhere to go. If you called a composable from a coroutine, the UI it emits would have nowhere to go.
    Can you share some code?
    AmrJyniat

    AmrJyniat

    10 months ago
    The fun that collect actions from VM is:
    private fun setObservers() {
        lifecycleScope.launch {
            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.taskDetailsActions.collect { action ->
                    when(action){
                        is TaskDetailsActions.ShowSureDeleteTaskDialog -> {
                           ShowSureDeleteTaskDialog() //trigger composable fun to show AlertDialog
                        }
                    }
                }
            }
        }
    }
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    10 months ago
    Right, so you probably want to have something like this:
    var showSureDeleteTaskDialog by mutableStateOf(false)
      private set
    
    private fun setObservers() {
      …
      is TaskDetailsActions.ShowSureDeleteTaskDialog -> {
        showSureDeleteTaskDialog = true
      }
    }
    and then in a composable,
    if (viewModel.showSureDeleteTaskDialog) {
      Dialog { … }
    }
    AmrJyniat

    AmrJyniat

    10 months ago
    Sorry for late response, this solution fine but the code becomes some boilerplate. I think to trigger the dialog from compose directly instead of submit the action to VM then observer it, right?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    10 months ago
    If that works, then sure that's an option, but it's probably a question of clean layering and grouping of responsibilities.