简体   繁体   中英

How to observe data in viewmodel LiveData + Courotine + MVVM + Retrofit

The problem is I could not get the response using LiveData and Courotine in the viewModel. Possibly I do not know the right way to do that. The call is

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

The repository is

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))
        }
    }
}

What I am trying to do in viewmodel is,

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)
            }
        }

And its not working. Could you please tell me what I am doing wrong? Thanks

It seems to me that the reason why you are not getting the result is because there are no Observers for the LiveData returned by authRepository.login(username, password)

You need to do something like:

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

This usually happens inside a Fragment or Activity which are LifeCyclerOwners .

Also, liveData {...} takes a suspend block, but it is not itself a suspend function. This means that login() does not need to be a suspend function.

Check below code for architecture using MVVM + Koin [ https://github.com/parthpatibandha/MvvmCleanKotlin ]

Retrofit interface

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

Repository

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)
        }
    }

Hope it helps you for understand MVVM with Koin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM