I'm following the MVVM architecture in my android app. (https://developer.android.com/jetpack/guide). All of my repository function returns a NetworkBoundResource object. You can read more about this design implementation from the jetpack guide link, or view the example project from google here
In this particular problem, I'm trying to re-fetch information over the network when I pull down on the screen.
Current working implementation
Fragment listener (triggered when screen pulled down)
binding.refresh.setOnRefreshListener {
profileViewModel.refreshUserProfile()
}
Then in my ViewModel I have a MutableLiveData that updates value on this function call
private val _refresh = MutableLiveData<Boolean>()
fun refreshUserProfile() {
_refresh.value = true
}
And when _refresh.value
changes, it triggers switchMap
val currentUserProfile: LiveData<Resource<UserProfile>> = _refresh.switchMap {
if (it) {
repository.getCurrentUserProfile(_username.value.toString())
} else {
AbsentLiveData.create()
}
}
Repository function
fun getCurrentUserProfile(username: String): LiveData<Resource<UserProfile>> {
return object : NetworkBoundResource<UserProfile, UserProfile>(AppExecutors.getInstance()) {
override fun saveCallResult(item: UserProfile) {
userProfileDao.update(item)
}
override fun shouldFetch(data: UserProfile?): Boolean {
return true
}
override fun loadFromDb(): LiveData<UserProfile> {
return userProfileDao.load(username)
}
override fun createCall(): LiveData<ApiResponse<UserProfile>> {
return networkService.userProfileService.getUserProfileAsync(
token,
username
)
}
}.asLiveData()
}
And then back at my fragment, I have an observer on this currentUserProfile
ViewModel variable
profileViewModel.currentUserProfile.observe(viewLifecycleOwner, { userProfileResult ->
when (userProfileResult.status) {...}
})
What I am trying to do
I would like to skip the step where I'm setting _refresh.value = true
. And instead observe the repository function directly like this:
val currentUserProfile: LiveData<Resource<UserProfile>> =
repository.getCurrentUserProfile(_username.value.toString())
But this implementation will not trigger the observer in the fragment.
Question I don't quite understand why I wasn't able to trigger observer with my second implementation. And I'm also unsure if my initial implementation is even optimal or correct. I would appreciate any sort of feedback especially if you are familiar with this type of design.