Reputation: 9994
I have following method in Repository which I call in ViewModel init method :
suspend fun fetchShows() {
_shows.value = Resource.loading()
dao.getShows().let { showsFromDb ->
flow {
if (showsFromDb.isEmpty()) {
if (context.isNetworkAvailable()) {
val apiShows = getRefreshedShows()
emit(Resource.success(apiShows))
} else {
emit(Resource.error(context.getString(R.string.failed_network_msg)))
}
} else {
emit(Resource.success(showsFromDb.asDomainModel()))
try {
val apiShows = getRefreshedShows()
emit(Resource.update(apiShows))
} catch (err: Exception) {
Timber.e(err)
}
}
}
}.flowOn(contextProvider.io)
.catch {
_shows.value = Resource.error(context.getString(R.string.failed_loading_msg))
}.collect {
_shows.value = it
}
}
here is my ViewModel :
class MainViewModel(
private val repository: ShowRepository
) : ViewModel() {
private val _shows = repository.shows
val shows: StateFlow<Resource<List<Show>>>
get() = _shows
init {
refreshShows()
}
fun refreshShows() {
viewModelScope.launch {
repository.fetchShows()
}
}
}
And I observe StateFlow in my Activity :
lifecycleScope.launch {
viewModel.shows.collect { resource ->
when (resource.status) {
Resource.Status.SUCCESS -> {
binding.loadingSpinner.hide()
binding.errorLayout.hide()
viewModelAdapter.submitList(resource.data)
}
Resource.Status.LOADING -> {
binding.loadingSpinner.show()
binding.errorLayout.hide()
}
Resource.Status.ERROR -> {
binding.loadingSpinner.hide()
binding.errorLayout.show()
binding.errorMsg.text = resource.message
}
Resource.Status.UPDATE -> {
viewModelAdapter.submitList(resource.data)
}
Resource.Status.IDLE -> {
}
}
}
}
Is there any better solution to remove Update state and use Success state instead since they are doing the same thing?
Full source code can be found : https://github.com/AliRezaeiii/TVMaze-Cache
Upvotes: 1
Views: 752
Reputation: 2752
If I understood correctly you want to do the same thing on success and update state.
lifecycleScope.launch {
viewModel.shows.collect { resource ->
when (resource.status) {
Resource.Status.UPDATE,
Resource.Status.SUCCESS -> {
binding.loadingSpinner.hide()
binding.errorLayout.hide()
viewModelAdapter.submitList(resource.data)
}
Resource.Status.LOADING -> {
binding.loadingSpinner.show()
binding.errorLayout.hide()
}
Resource.Status.ERROR -> {
binding.loadingSpinner.hide()
binding.errorLayout.show()
binding.errorMsg.text = resource.message
}
Resource.Status.IDLE -> {
}
}
}
}
OR you can simply avoid Resource.update(apiShows)
by using Resource.success(apiShows)
in your repository.
Upvotes: 1