nilTheDev
08/25/2021, 6:52 AMLiveData
of type MutableLiveData<MutableList<User>>
.
I have an issue.
If I update the value
by another MutableList<User>
the changes are emitted to the observers.
However, if I simply add other elements to the MutableList<User>
, that is already initialised in the LiveData
, the changes are not emitted.
Here is what I am doing...
//other codes
private val _users: MutableLiveData<MutableList<User>> = MutableLiveData<MutableList<User>>()
init {
_users.value = mutableListOf<User>()
}
val uiScope = CoroutineScope(Dispatchers.Main + Job())
fun loadUsers(){
uiScope.launch{
// this works perfectly
_users.value = fetchUsers() as MutableList<User>
// this doesn't work... no idea why
_users.value.addAll(fetchUsers())
}
}
suspend fun fetchUsers(): List<User>{
return withContext(<http://Dispatchers.IO|Dispatchers.IO>){
//fetch users asynchronously
}
}
This is just an emulation of the actual program. That actual code is not that trivial.divid3d
08/25/2021, 7:24 AMsetValue()
every time u want to dispatch new value to active observers. In second case you're doing nothing with the result. U could do something like:
val newUsers = _users.value.addAll(fetchUsers)
_users.value = newUsers
nilTheDev
08/25/2021, 8:09 AM_users.value = fetchUsers()
does indeed call the setValue()
. Maybe that's why it is working.
In the second case I am updating the MutableList<User>
stored inside the LiveData
. Does it have no effect because I am calling a suspend
function?
I am no sure whether your code would even type-check.
val newUsers = _users.value.addAll(fetchUsers)
_users.value = newUsers
_users.value.addAll(fetchUsers())
would return a Boolean
. And we can only store MutableList<User>
inside _users.value
.divid3d
08/25/2021, 8:28 AMval newUsers =_users.value.apply{
addAll(fetchUsers)
}
_users.value = newUsers
Aniket Kadam
08/25/2021, 9:29 AMAdam Powell
08/25/2021, 2:20 PMnilTheDev
08/25/2021, 2:23 PMLiveData
. Why is it like that?
I have even tried this,
// inside viewModel
// _users is a MutableLiveData<MutableList<User>>
fun loadUsers(){
val uiScope = CoroutineScope(Dispatchers.Main + Job())
uiScope.launch{
_users.value.add(User())
}
}
But it doesn't emit the value.
In contrast, this code works,
// inside viewModel
// _users is a MutableLiveData<MutableList<User>>
fun loadUsers(){
_users.value.add(User())
}
Why does it work this way? Apparently, LiveData
doesn't notify the observers about the changes while done asynchronously, even if it is the main thread. But it works when it is synchronous.Adam Powell
08/25/2021, 2:33 PMnilTheDev
08/25/2021, 2:56 PM