Как повторить запрос внутри моей viewmodel - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь повторить логику c получения данных из Firebase, что мое приложение делает следующее:

Если нет соединения inte rnet, это вызовет ресурс сбоя и покажет кнопку повтора, но когда я нажимаю эту кнопку, кажется, что модель представления больше не запрашивает данные, а просто показывает мой прогресс без повторного запроса данных в мой репозиторий

UI

 viewModel.getPrizes.observe(viewLifecycleOwner, Observer { it ->
            when(it){
                is Resource.Loading -> {
                  // Loading...
                }
                is Resource.Success -> {
                    hideProgress()
                    setArrayData(it.data)
                }
                is Resource.Failure -> {
                    hideProgress()
                    hidePrizes()
                    retry_constrain.visibility = View.VISIBLE
                    btn_retry.setOnClickListener{
                        viewModel.getPrizes
                        showProgress()
                        retry_constrain.visibility = View.GONE
                    }
                    Toast.makeText(
                        requireContext(),
                        "An error has ocourred:${it.throwable.message}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        })

То, что я вижу здесь, находится в моем Resource.Failure, чтобы запросить данные снова после нажатия моего btn_retry, но вместо этого он показывает только мой индикатор выполнения, и ничего не происходит

ViewModel

class PrizesViewModel(private val useCase:IPrizes): ViewModel() {

    val getPrizes = liveData(Dispatchers.IO) {
        emit(Resource.Loading())
        try{
            val prizes = useCase.fetchPrizes()
            emit(prizes)
        }catch (e:Exception){
            Crashlytics.logException(e.cause)
            emit(Resource.Failure(e.cause!!))
        }
    }
}

Почему не происходит повторное извлечение моих значений после повторного вызова viewModel.getPrizes в моем Resource.Failure?

Ответы [ 2 ]

2 голосов
/ 08 января 2020

У LiveData из второго вызова viewModel.getPrizes нет прикрепленного Observers, и, следовательно, он не получит значение, пока оно не будет.

Вам нужно будет позвонить viewModel.getPrizes.observe(...) снова внутри текущего Observer, что не оптимально.

Вам придется немного переосмыслить свой дизайн, чтобы вы могли инициировать новый вызов на useCase.fetchPrizes() и все же получить новое значение, наблюдая за исходным LiveData.

0 голосов
/ 08 января 2020

То, что я в итоге сделал, было преобразованием, так как преобразование может запускаться всякий раз, когда изменяется изменяемое значение, я могу повторить всю сопрограмму, делая это

 private val shouldRetry = MutableLiveData<Boolean>()
    val fetchPrizes: LiveData<Resource<Prizes>> = Transformations.switchMap(shouldRetry) {
        liveData(context = viewModelScope.coroutineContext + Dispatchers.IO) {
          emit(Resource.Loading())
        try{
            val prizes = useCase.fetchPrizes()
            emit(prizes)
        }catch (e:Exception){
            Crashlytics.logException(e.cause)
            emit(Resource.Failure(e.cause!!))
        }
        }
    }

    fun retryData(retry: Boolean) {
        shouldRetry.value = retry
    }

Затем из моего пользовательского интерфейса я просто вызываю viewModel.retryData(true) когда захочу

...