I need to get an Observer event when the item is added to the List of LiveData.
// mutable live data list of shoes
private var _shoesList = MutableLiveData<List<Shoe>>()
val shoesList: LiveData<List<Shoe>>
get() = _shoesList
When I add a new item to the list
_shoesList.value?.plus(Shoe(name,sizeDouble,company,description))
_shoesList.value = _shoesList.value // so the observer gets notified
The observer code:
val viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
The code inside the observer block is never reached
viewModel.shoesList.observe( viewLifecycleOwner , Observer { newShoe ->
Log.i("ShoeListFragment","i am inside the observer block")
})
I am still a beginner so any help would be apprciated 🙂
2
Answers
plus
returns a new list which is the original list with your newShoe
added to it – it doesn’t affect the original list.plusAssign
adds to the original.Those are both
operator
functions (see theoperator
keyword) which means you can use them like:If you’re not familiar with
+=
, the longer version isshoesList = shoesList + newShoe
. So you can tell you’re reassigning the value ofshoesList
with that one. Just doingshoesList + newShoe
doesn’t change anything – you just combine them and then do nothing with the result.But your
LiveData
holds an immutableList
type, not aMutableList
– so you can’t add to that. You can’t useplusAssign
here, you need to useplus
to create a new list (the original combined with the new element) and then assign it to yourLiveData
:So not much of a change from what you already had, but hopefully that gives you a better idea of what’s going on! If you were using a
MutableList
, you could just do plusAssign, but yeah you’d have to reassign thevalue
to nudge it into updating its observers.And honestly, creating a new list is usually safer, because you’re not modifying the original one, which other things might have stored a reference to. For example, if you’re using a
DiffUtil
in aRecyclerView
, which compares the old list to a new one… if you change the old one and then push that as the new one, theDiffUtil
is looking at two references to the same object. So there’s no difference, meaning it doesn’t trigger an update (the old list did change, but all it can do is compare to the new one, which is the same list). You can get other bugs changing old data in the background like that, while outwardly pushing a "new" valueMutableLiveData
contains a list of shoes, you need to declare them separately in your view model:And expose
LiveData
to anyone who wants to listen to data changes:whenever you want to add a new
Shoe
, just add it in the_shoes
listAnd then update the mutableLiveData to notify listener :
_shoes
is a private variable, add this method to be able to add a newshoe
:Here is the complete code :
call this line of code, every time you want to add a new shoe