'How to observe ViewModel LiveData changes from Compose state holder class?
I am following the Android Developers Managing State in Compose guide. https://developer.android.com/jetpack/compose/state#managing-state
I have implemented my own state holder which takes the viewModel as parameter as per diagram below. Inside the state holder I have State objects like mutableStateOf() which trigger re-composition.
The issue I am having is how to have MyStateHolder observe changes to LiveData in MyViewModel. As MyStateHolder is a POJO, I cannot use features such as observeAsState().
It seems odd that google recommend this approach but provide no out of the box way to do this.
How can I observe changes from viewModel in state holder? Am I missing something?
class MyStateHolder(
private val viewModel: MyViewModel,
) {
//initialise state variables and observe _portfolioData
var portfolioDataMap = mutableStateMapOf<String, PortfolioDataModel>().apply {
putAll(viewModel.portfolioData.value!!)
viewModel.portfolioData.observeAsState() /*error here: cannot observeAsState in POJO*/
}
}
class MyViewModel : ViewModel() {
private val _portfolioData: MutableLiveData<Map<String, PortfolioDataModel>> =
MutableLiveData()
val portfolioData: LiveData<Map<String, PortfolioDataModel>>
get() = _portfolioData
fun setStateEvent(mainStateEvent: MainStateEvent<String>) {
//send events to update _portfolioData
}
}
Solution 1:[1]
Observing life model requires a lifecycle owner. You can add this parameter to your state holder:
class MyStateHolder(
private val lifecycleOwner: LifecycleOwner,
private val viewModel: MyViewModel,
) {
//initialise state variables and observe _portfolioData
var portfolioDataMap = mutableStateMapOf<String, PortfolioDataModel>().apply {
putAll(viewModel.portfolioData.value!!)
}
init {
viewModel.portfolioData.observe(lifecycleOwner) {
portfolioDataMap.clear()
portfolioDataMap.putAll(it)
}
}
}
And during initialization you can pass it from LocalLifecycleOwner.current, basically like this:
@Composable
fun rememberMyStateHolder() : MyStateHolder {
val lifecycleOwner = LocalLifecycleOwner.current
val viewModel = viewModel<MyViewModel>()
// consider using rememberSaveable instead of remember with a custom saver
// in case of configuration change, e.g. screen rotation
return remember(lifecycleOwner, viewModel) {
MyStateHolder(lifecycleOwner, viewModel)
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Pylyp Dukhov |

