This answer show us how can we use liveData
in the repository to return a LiveData
to ViewModel
which the View
will observe.
Now, what if we want to use SavedStateHandle
? How can we transform the following code to use liveData{}
from LiveData-Ktx?
ViewModel:
private val _itemLiveData = stateHandle.getLiveData<MyItem>(KEY, MyItem())
val itemLiveData: LiveData<MyItem> = _itemLiveData
suspend fun nextPage() {
viewModelScope.launch {
val item = repoCall...
stateHandle.set(KEY, item)
}
}
Activity:
viewModel.itemLiveData.observe(this, Observer {
lifecycleScope.launch {/*...update ui...*/}
})
Will we benefit from using liveData{... emit()}
?
I can see 3 advantages of using SavedStateHandle
:
1 - Restore your viewModel state
2 - It calls .value()
for us when we use stateHandle.set()
3 - stateHandle.getLiveData
helps us initialize the value (this is also helpful with Data Binding
for example)
I think you can do something like this
class SomeViewModel(
private val savedStateHandle: SavedStateHandle
repository:ItemsRepository) : ViewModel() {
companion object {
private const val PAGE_KEY = "page_key"
}
private val _page = MutableLiveData<PageId>(savedStateHandle.get(PAGE_KEY))
private val _itemLiveData = Transformations.switchMap(_page) { pageId -> repository.getNextPage(pageId) }
val itemLiveData: LiveData<MyItem> = _itemLiveData
suspend fun nextPage(pageId: PageId) {
_page.postValue(pageId)
}
override fun onCleared() {
super.onCleared()
savedStateHandle.set(PAGE_KEY, _page.value)
}
}
class ItemsRespository {
fun getNextPage(pageId:PageId) = liveData() {
....
emit(someData)
}
}
Let me know if it helped you. P.S. PageId it can be number of current page or other any page identifier