Search code examples
androidkotlinviewmodelandroid-livedataandroid-jetpack-compose

Composable doesn't recompose although LiveData changes


I simply want to add a Node to a List when the user clicks a button and display it in a composable LazyColumn.

Here is how I thought it would work: VieModel:

    private val _nodeList: MutableLiveData<MutableList<Node>> = MutableLiveData()
    val nodeList: LiveData<MutableList<Node>> = _nodeList

    fun onNodeListChange(newNode: Node){
        _nodeList.value?.add(newNode)
}

and in my Composable I try to observe it by calling:

val vm = getViewModel<MainViewModel>()
val nodeList: List<Node> by vm.nodeList.observeAsState(listOf())

In the onClick of the Button I call:

val newNode = Node(title, body)
vm.onNodeListChange(newNode)

The node gets added to the nodeList in the ViewModel but the Composable wont recompose. What am I doing wrong?


Solution

  • Your LiveData is not changing. You are just adding a new item to the list stored within the LiveData. For a LiveData to notify it's observers, the object returned by livedata.getValue() must occupy a different memory space from the one supplied through livedata.setValue() One quick and dirty solution would be:

    _nodeList.value = _nodeList?.value?.toMutableList()?.apply{add(newNode)}

    In Jetpack compose you probably want to use a SnapShotStateList for an observable list instead of a LiveData<List<T>>