Show DataStore protobuf settings in Jetpack Compose

Viewed 377

I'm having an issue trying to display the data saved in my DataStore on startup in Jetpack Compose.

I have a data store set using protocol buffers to serialize the data. I create the datastore

val Context.networkSettingsDataStore: DataStore<NetworkSettings> by dataStore(
     fileName = "network_settings.pb",
     serializer = NetworkSettingsSerializer
)

and turn it into a livedata object in the view model

val networkSettingsLive = dataStore.data.catch { e ->
    if (e is IOException) { // 2
        emit(NetworkSettings.getDefaultInstance())
    } else {
        throw e
    }
}.asLiveData()

Then in my @Composable I try observing this data asState

@Composable
fun mycomposable(viewModel: MyViewModel) {
    val networkSettings by viewModel.networkSettingsLive.observeAsState(initial = NetworkSettings.getDefaultInstance())
    val address by remember { mutableStateOf(networkSettings.address) }
    Text(text = address)
}

I've confirmed that the data is in the datastore, and saving properly. I've put some print statements in the composible and the data from the datastore makes it, eventually, but never actually displays in my view. I want to say I'm not properly setting my data as Stateful the right way, but I think it could also be not reading from the data store the right way. Is there a display the data from the datastore in the composable, while displaying the initial data on start up as well as live changes?

1 Answers

I've figured it out. What I had to do is define the state variables in the composable, and later set them via a state controlled variable in the view model, then set that variable with what's in the dataStore sometime after initilization.

class MyActivity(): Activity {
    private val viewModel: MyViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        MainScope.launch {
            val networkSettings = viewModel.networkSettingsFlow.firstOrNull()
            if (networkSettings != null) {
                viewModel.mutableNetworkSettings.value = networkSettings
            }
        }
    }
}

class MyViewModel(): ViewModel {
    val networkSettingsFlow = dataStore.data
    val mutableNetworkSettings = mutableStateOf(NetworkSettings.getInstance()
}

@Composable
fun NetworkSettings(viewModel: MyViewModel) {
     val networkSettings by viewModel.mutableNetworkSettings
     var address by remember { mutableStateOf(networkSettings.address) }
     address = networkSettings.address  
     Text(text = address)
}
Related