Как наблюдать данные в viewmodel LiveData + Courotine + MVVM + Retrofit - PullRequest
0 голосов
/ 07 февраля 2020

Проблема в том, что я не смог получить ответ, используя LiveData и Courotine в viewModel. Возможно, я не знаю правильный способ сделать это. Вызов

interface AuthApiService {
    @POST("v2/5e3cba6a2d00008709d958d0")
    @FormUrlEncoded
    suspend fun login(
        @Field("username") username: String,
        @Field("password") password: String
    ): Response<AuthToken>
}

Репозиторий

class AuthRepository
@Inject
constructor(
    val authApiService: AuthApiService
) {
    suspend fun login(username: String, password: String) = liveData {
        emit(GenericResult.Loading(null))
        try {
            emit(GenericResult.Success(authApiService.login(username, password)))
        } catch (ioException: Exception) {
            emit(GenericResult.Error(ioException))
        }
    }
}

Я пытаюсь сделать в viewmodel,

viewModelScope.launch {
            val result = authRepository.login(username, password)

            when (result.value) {
                is GenericResult.Loading -> isLoading.postValue(true)
                is GenericResult.Success -> authToken.postValue((result.value as GenericResult.Success<Response<AuthToken>>).data.body())
                is GenericResult.Error -> onMessageError.postValue((result.value as GenericResult.Error).exception)
            }
        }

И он не работает. Не могли бы вы сказать мне, что я делаю не так? Спасибо

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Мне кажется, что причина, по которой вы не получаете результат, заключается в том, что LiveData для *1002*, возвращаемого authRepository.login(username, password)

, не требуется. Вам нужно сделать что-то вроде:

val result = authRepository.login(username, password)
result.observe(someLifeCycleOwner, Observer {...})

Это обычно происходит внутри Fragment или Activity, которые LifeCyclerOwners.

Кроме того, liveData {...} занимает блок suspend, но сам по себе не suspend функция. Это означает, что login() не обязательно должно быть функцией suspend.

0 голосов
/ 07 февраля 2020

Проверьте приведенный ниже код для архитектуры с использованием MVVM + Koin [https://github.com/parthpatibandha/MvvmCleanKotlin]

Модифицированный интерфейс

interface MovieApiService {
    @POST(ApiConstant.API_MOVIES)
    fun getAllMovieList(
        @Query("page") page : String
    ): Deferred<FlickerImageListRS>
}

Хранилище

class HomeRepository constructor(
    private val homeLocalDataSource: HomeLocalDataSource,
    private val homeRemoteDataSource: HomeRemoteDataSource
) : BaseRepository(), HomeRepo {
    override suspend fun getAllMovieList(flickerImageListPRQ: FlickerImageListPRQ): Either<MyAppException, FlickerImageListRS> {
        return either(homeRemoteDataSource.getAllMovieList(flickerImageListPRQ))
    }
}

ViewModel

class MovieListingViewModel constructor(private val homeRepo: HomeRepo) : BaseViewModel() {

    val movieListRSLiveData: MutableLiveData<FlickerImageListRS> = MutableLiveData()
    fun getMovieList(page : String) {
        launch {
            postValue(homeRepo.getAllMovieList(FlickerImageListPRQ(page)), movieListRSLiveData)
        }
    }

Надеюсь, это поможет вам понять MVVM с Koin.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...