androidandroid-jetpack-datastore

How to use Datastore in Compose?


In my app the viewmodel exposes a state representing the state of an api call, lets say for example the result of a login.

 when {
    viewModel?.signinState?.value?.isLoading == true -> {
           ProgressView()
     }

     viewModel?.signinState?.value?.data != null -> {
          saveSigninData()
      }
 }

where saveSigningData should save inside datastore some data about the user, the problem is I can't understand how to do it.

Most of online examples save data inside a LaunchedEffect lamda, since coroutine scope can't be used inside a composable how should I proceed?

Is it wrong to observe state of an api call inside the composable function?


Solution

  • I would recommend that you take a closer look at how recomposition works. You can experiment, for example, with printing a string in the logcat.

    I will try to explain what you are doing in this code block. So firstly you do a check of viewModel?.signinState?.value and it will be performed on each recomposition.

    For optimized approach you can use LaunchedEffect, to call your saveSigninData() only when the value of viewModel?.signinState?.value?.data was changed:

    LaunchedEffect(){
        snapshotFlow {viewModel?.signinState?.value?.data}
            .collect{ data ->
                if(data != null) saveSigninData()
            }
    }
    

    But, actually, I would recommend that you call this saveSigninData() method inside the ViewModel itself, since the check you have includes properties from its ViewModel, so you do not need to put this logic in the screen

    However, you can continue to use the logic like

    if (...) ProgressView()
    

    because it's also a composable function and it won't re-render due to such a check