Jetpack Compose with Coroutine’s StateFlow

I am running into a strange issue while using StateFlow with Jetpack Compose, where I am not receiving the updated value in the StateFlow. This is the code how I try to observe the Stateflow as suggested in the examples.

@Composable
fun List(homeViewModel: HomeViewModel) {

val appState by homeViewModel.stateFlow.collectAsState()

if (appState.isLoading) {
    CircularProgressIndicator()
}
MaterialTheme {
    LazyColumn {
        items(appState.names) { name ->
            Name(name = name.name)
        }
    }
}

}

I receive the initial value correctly but not the updated value

setContent {
  Surface(color = MaterialTheme.colors.background) {
                List(mainViewModel.homeViewModel)
      }
}

I have defined my stateFlow in the viewModel like this

internal val stateFlow = MutableStateFlow(AppState())

I update the value by this

stateFlow.value = AppState(loading = false, listOf("1", "2"))

my AppState Pojo

data class AppState(val names: List<Names> = emptyList(), val isLoading: Boolean = true, val error: Throwable? = null)

The problem is when I update the value of stateFlow like above I expect the composable to recompose and update the value but the updated value never comes to my composable method above. I need a little help on where I am going wrong

PS: I haven’t tried this on LiveData yet

Answer

Going on basis of https://github.com/cyph3rcod3r/D-KMP-Architecture project you mentioned on twitter:

Issue is that in following code a new instance of HomeViewModel is being created each time getter is called meaning that homeViewModel.stateFlow that you’re observing and instance that you’re updating are different.

class MainViewModel : ViewModel() {
     val homeViewModel get() = HomeViewModel()

    fun getListOfNames(){
        homeViewModel.getList()
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *