Am I missing something or is it not possible to attach a listener to the new Android Jetpack Preference Datastore? I thought the whole point of using Flow is that we can call flow.toLiveData() on the Preference Datastore and observe changes to the value changes.
Here is how I am getting a Flow from the Datastore.
val taxRatePreferenceFlow: Flow<TaxRate> = dataStore.data
.catch { exception ->
if (exception is IOException){
emit(emptyPreferences())
} else {
throw exception
}
}.map { preferences ->
val name = preferences[PreferencesKeys.TAX_LABEL] ?: "Tax"
val rate = preferences[PreferencesKeys.TAX_RATE] ?: Constants.DEFAULT_TAX_RATE.toFloat()
val type = TaxType.valueOf(preferences[PreferencesKeys.TAX_TYPE] ?: TaxType.ON_ITEMS.name)
TaxRate(name, rate, type)
}
I was hoping to convert the Flow to a LiveData like so in the ViewModel and listen for changes until the observers are removed.
totalAmountLiveData.addSource(taxRateFlow.asLiveData()){ taxtRate ->
taxtRate?.let {
updateTaxAmount(it)
}
}
However this observer only emits the saved value and does not update as the values are updated. Exiting and re-entering the screen shows the updated value.
And here is how I update each value in the DataStore
suspend fun updateTaxLabel(newTaxLabel: String){
dataStore.edit { preferences ->
preferences[PreferencesKeys.TAX_LABEL] = newTaxLabel
}
}
What am I missing, should I be using collect instead of map? If yes, can someone show me an example of how to use Flow collect in this context.
You can directly observe the flow as a liveData, no need to add it as source for another live data.
Your code would change from
to
In this case you can directly see your data changing the datastore and perform the functions accordingly.