Reputation: 641
I have one LiveData object that holds a list of Users and I am trying to transfer over the data to another LiveData object to be used elsewhere.
I am using MVVM with Room so I get LiveData from the database and on the ViewModel, I am trying to convert the User object in the LiveData to a Person object to show in the UI.
So I have one variable that is LiveData<List<User>>
class User(var firstName: String, var lastName: String, var age: Integer)
and I am trying to convert it to LiveData<List<Person>>
(as an example)
class Person() {
lateinit var firstName: String
lateinit var age: Integer
}
and the way I am trying to change them is by using LiveData Transformations.map
ViewModel:
val list2: LiveData<List<User>> = repo.getAll()
var liveList: LiveData<ArrayList<Person>> = MutableLiveData()
liveList = Transformations.map(list2) { list ->
val newList: ArrayList<Person> = ArrayList()
list?.forEach {
val temp = Person()
temp.firstName = it.firstName
temp.age = it.age
newList.add(temp)
}
return@map newList
}
but when I run it, it crashes or doesn't update the UI.
Thanks!
Upvotes: 2
Views: 7297
Reputation: 570
The main problem with your code is that it uses var
in var liveList: LiveData
instead of using val
.
You should declare the liveList
variable like this:
val liveList = Transformations.map(list2) { list ->
...
}
Generally, a LiveData
variable should always be declared with val
. The reason is that the purpose of LiveData
is to allow us to observe the up-to-date value held by the LiveData
. We do it by code like this:
liveList.observe(this) { list ->
showList(list)
}
With this code, we ensure that the updated list is always shown. Whenever the list
value which is held by liveList
changes, the UI is updated as a result. But if the liveList
itself also changes, the code will only observe the first LiveData
of the liveList
variable, and the UI will not be updated correctly.
Upvotes: 2
Reputation: 1417
val liveList = MutableLiveData(repo.getAll().value.orEmpty().map { user ->
Person(user.firstName, user.age)
})
This would be a more compact way, you could pull out the repo.getAll() call into its own variable if you like
Upvotes: 0