I am new to MVVVM and retrofit i have successfully implemented MVVM and is able to move data from retrofit to repository then Repository to ViewModel and view.
While doing this i came up to a massive confusion which is mentioned below. In first scenario my code looks like this:
Repository:
fun iniateOTPprocess() : LiveData<GenericResponse> {
RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {
override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
super.onResponse(call, response)
result.value = response.body()
}
}
)
return result
}
ViewModel:
class LoginViewModel2(application: Application) : AndroidViewModel(application) {
lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()
init {
data.addSource(result , Observer {
data.postValue(it)
})
}
fun onLoginBtnCLicked() {
initiateOTP()
}
private fun initiateOTP() {
result = repository.iniateOTPprocess()
}
fun getResponse() : MediatorLiveData<GenericResponse>{
return data
}
}
The Mediator live data is never updated this way once the data is updated.
But if i change this code to
Repository
class LoginRepository(var application: Application) {
var callback: RetrofitCallback = RetrofitCallback()
var result = MutableLiveData<GenericResponse>()
fun iniateOTPprocess() {
RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {
override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
super.onResponse(call, response)
result.value = response.body()
}
}
)
}
fun getData(): MutableLiveData<GenericResponse> {
return result
}
}
ViewModel
class LoginViewModel2(application: Application) : AndroidViewModel(application) {
lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()
init {
data.addSource(repository.getData(), Observer {
data.postValue(it)
})
}
fun onLoginBtnCLicked() {
initiateOTP()
}
private fun initiateOTP() {
repository.iniateOTPprocess()
}
fun getResponse() : MediatorLiveData<GenericResponse>{
return data
}
}
This code starts working magically. In the view i am observing getResponse() method in both the scenarios. Can anyone here help with the confusion and can explain where the magic is happening. Thanks in advance.
In your first scenario, even though you are updating result
through this function:
private fun initiateOTP() {
result = repository.iniateOTPprocess()
}
You won't be able to observe the changes in this new result
instance since you are already observing the first result
instance created when you instantiate your ViewModel
:
var result = MutableLiveData<GenericResponse>() // you are observing this instance
init {
// this result never gets updated
data.addSource(result , Observer {
data.postValue(it)
})
}
...
fun getResponse() : MediatorLiveData<GenericResponse>{
return data
}
your code not following MVVM pattern every single live data must have observer, when you declare at init{} the value its not ready yet because its async. if you change to :
data.addSource(repository.iniateOTPprocess(), Observer {
data.postValue(it)
})
the code will working,this is the best source to learn MVVM and livedata pattern google codelabs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.