Excellent article! I have doubt in one of the snippet shown here.
Inside PeopleDetailsViewModel we have following method.
fun getPeopleDetails(id: Int): LiveData<People> {
peopleId.value = id
val peopleDetails = Transformations.switchMap<Int, People>(peopleId) { id ->
peopleRepository.findPeople(id)
}
return peopleDetails
}
What it does is, every-time we call getPeopleDetails, it will always initialise peopleDetails and return the new instance. Actually this kills the purpose of having Transformations.switchMap. I believe it should be update to following snippet.
Updated ViewModel code
init {
peopleData = Transformations.switchMap<Int, People>(peopleId) { id ->
peopleRepository.findPeople(id)
}
}
fun getPeopleLiveData() = peopleData
fun refreshPeople(id: Int) {
peopleId.value = id
}
Fragment Code
viewModel.getPeopleLiveData().observe(this, Observer { peopleDetails ->
populatePeopleDetails(peopleDetails)
})
// Find people with provided id
val peopleId = arguments?.getInt(getString(R.string.people_id))
peopleId?.let {
viewModel.refreshPeople(peopleId)
}
So in above case, whenever id changes, refreshPeople method will be called by fragment, it will set new id on peopleId LiveData, which will in turn trigger switchMap call to findPeople.
Hi @vipshah, thanks for highlighting and yes, your understanding is perfect! The above code is demonstrated in such way just to introduce audiences with the LiveData Transformations feature and explain with easy, of course in real use-cases there are always room for improvements just like you showed one. We will definitely update that in the next revisions. Thanks again!
Glad that you liked this article and learned something new from it!
As a professional, you should go for the app architecture which is more comfortable to all your team members and allows you to write simpler and maintainable code. MVVM is a better choice for such case now a days!
My personal favourite is MVVM + Databinding for architecting Android apps.