class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<User>> by lazy {
MutableLiveData().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<User>> {
return users
}
private fun loadUsers() {
// Do an asynchronous operation to fetch users.
}
}
Am trying to implement this way and its not compiling :
class MyViewModel : ViewModel() {
private val users: MutableLiveData<List<String>> by lazy {
return MutableLiveData().also {
loadUsers()
}
}
fun getUsers(): LiveData<List<String>> {
return users
}
private fun loadUsers() {
users.postValue(listOf("Tarun", "Chawla"))
}
}
Mostly am not understanding the by lazy here. The example on android website seems wrong as loadUsers() is not returning anything which can be a delegate for users. can you please help me understanding above piece of code.
=======================================================
This is how I implemented:
private val users : MutableLiveData<List<String>> by lazy {
MutableLiveData<List<String>>().also {
loadUsers(it)
}
}
init {
Log.e("Tarund", "View Model created")
}
override fun onCleared() {
super.onCleared()
Log.e("Tarund", "View Model deleted")
}
fun getUsers(): LiveData<List<String>> {
return users
}
private fun loadUsers(users : MutableLiveData<List<String>>) {
users.postValue(listOf("Tarun", "Chawla"))
}
}
But if anyone can confirm if first example code above which I copy pasted from : https://developer.android.com/topic/libraries/architecture/viewmodel#kotlin is wrong
No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data.
ViewModel : Provides data to the UI and acts as a communication center between the Repository and the UI. Hides the backend from the UI. ViewModel instances survive device configuration changes. LiveData : A data holder class that follows the observer pattern, which means that it can be observed.
There are three steps to setting up and using a ViewModel: Separate out your data from your UI controller by creating a class that extends ViewModel. Set up communications between your ViewModel and your UI controller. Use your ViewModel in your UI controller.
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
The code in the Android documentation is wrong.
The lazy construction itself is fine: loadUsers() doesn't need to return anything because the function also is defined as:
inline fun <T> T.also(block: (T) -> Unit): T
that means that in here:
private val sources: String by lazy {
String().also {
loadSources()
}
}
the block also {} will return the empty String created with String() that can be assigned using lazy initialization to the val users
The error trying to compile the Android docs code is:
Type inference failed: Not enough information to infer parameter T in constructor MutableLiveData()
that means that the compiler is not able to infer the type of the MutableLiveData instance created using the constructor wihtout type.
Without the apply block the compiler will be able to compile it because it can easily infer the type from the val definition:
private val sources: MutableLiveData<List<User>> by lazy {
MutableLiveData()
}
but adding the apply block goes back to the generic type and the compiler cannot infer it. So the solution, as you did, is specifying the type hold in the MutableLiveData container:
private val sources: MutableLiveData<List<User>> by lazy {
MutableLiveData<List<User>>().also {
loadSources()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With