cashapp / molecule

Build a StateFlow stream using Jetpack Compose
https://cashapp.github.io/molecule/docs/1.x/
Apache License 2.0
1.85k stars 80 forks source link

Molecule does not work properly with TextField #223

Closed namig-tahmazli closed 1 year ago

namig-tahmazli commented 1 year ago

Hi I have a simple setup like this


class ViewPresenter {
    data class ViewModel(val text: String, val isButtonEnabled: Boolean)
    private var text: String by mutableStateOf("")
    private val scope = CoroutineScope(job + app.cash.molecule.AndroidUiDispatcher.Main)
    val viewModel: StateFlow<ViewModel> = scope.launchMolecule(clock = ContextClock) {
           ViewModel(
        text = text,
        isButtonEnabled = text.isNullOrBlank().not()
       )
    }

    fun onTextChanged(newText: String) {
          text = newText
    }
}

@Composable
fun View(presenter: ViewPresenter) {
    val model by presenter.viewModel.collectAsState()
    Column {
        TextField(
            value = model.text,
            onValueChanged = presenter::onTextChanged
        )
        Button(
                onClick = {},
            enabled = model.isButtonEnabled
        ) {
                Text("Login")
        }
    }
}

But it does not work properly. The TextField value never updated.

mattprecious commented 1 year ago

I wrote a test for this and it passes, so I suspect it's something to do with some wiring code not included here. Ex: the job is being canceled or your presenter instance is changing and the UI code is not handling that correctly. If you have a standalone reproducible sample then I can take another look.

  @Test
  fun test() = runTest {
    val job = Job()
    val clock = BroadcastFrameClock()
    val scope = CoroutineScope(coroutineContext + job + clock)
    var text by mutableStateOf("")

    val flow = scope.launchMolecule(ContextClock) {
      text
    }

    assertEquals("", flow.value)

    text = "hey"

    runCurrent()
    clock.sendFrame(0)
    assertEquals("hey", flow.value)

    job.cancel()
  }
JakeWharton commented 1 year ago

It's probably #63 where the issue is more the interaction with Compose UI and not Molecule itself.