https://kotlinlang.org logo
#android
Title
# android
s

Somesh

10/31/2019, 6:15 AM
Hello Guys, I am having hard time figuring out how I can connect my
Repository
and `ViewModel`'s livedata in-case of
@GET
request and observe them in fragment. I don't have this problem when the request type is
@POST
because I can use
Transformation.switchMap
on body and whenever the body changes repository's function gets invoked and emit value to the response live data something like this
Copy code
val matchSetsDetail: LiveData<Resource<MatchDetailBean>> = Transformations.switchMap(matchIdLiveData) { matchId ->
        val body = MatchSetRequest(matchId)
        repository.getMatchSet(body)
    }
but in case of
@GET
request I have several query parameter the my View supplies I have this retrofit API call in repository class and the code looks like this
Copy code
fun checkInCheckOutUser(apiKey: String, userId: Int, status: String, latitude: Double, longitude: Double, checkedOn: Long): LiveData<Resource<BaseResponse>> = liveData {
        emit(Resource.Loading())
        try {
            val response: Response<BaseResponse> = ApiClient.coachApi.checkInCheckOutUser(apiKey, userId, status, latitude, longitude, checkedOn)
            if (response.isSuccessful && response.body() != null) {
                if (response.body()!!.isValidKey && response.body()!!.success) {
                    emit(Resource.Success(response.body()!!))
                } else {
                    emit(Resource.Failure(response.body()!!.message))
                }
            } else {
                emit(Resource.Failure())
            }
        } catch (e: Exception) {
            emit(Resource.Failure())
        }
    }
and
ViewModel
Copy code
class CheckInMapViewModel : ViewModel() {
    val checkInResponse: LiveData<Resource<BaseResponse>> = MutableLiveData()

    fun checkInCheckOut(apiKey: String, userId: Int, status: String, latitude: Double, longitude: Double, checkedOn: Long): LiveData<Resource<BaseResponse>>  {
        return repository.checkInCheckOutUser(apiKey,userId,status,latitude,longitude,checkedOn)
    }
}
Main problem is I want to observe
checkInResponse
but don't know how to pass repository's livedata same as I did with my post request above using
Transformations.switchMap
. Can anyone help me with this case?
p

pavi2410

10/31/2019, 7:54 AM
You could write your VM as
Copy code
class CheckInMapViewModel : ViewModel() {
    val _checkInResponse = MutableLiveData()

val checkInResponse: LiveData<Resource<BaseResponse>
    get() = _checkInResponse

    fun checkInCheckOut(apiKey: String, userId: Int, status: String, latitude: Double, longitude: Double, checkedOn: Long)  {
        _checkInResponse.value = repository.checkInCheckOutUser(apiKey,userId,status,latitude,longitude,checkedOn)
    }
}
and in
Activity
Copy code
checkInMapViewModel.checkInResponse(this) { /* observe */}

checkInMapViewModel.checkInCheckOut(...) // Refreshes livedata
s

Somesh

10/31/2019, 8:45 AM
@pavi2410 Thanks for reply. As you can see my repository function emits a live data but with your approach it expecting
Resource<BaseResponse>
. I simply can not do
_checkInResponse.value = repository.checkInCheckOutUser(apiKey,userId,status,latitude,longitude,checkedOn)
because of this.
k

kristianconk

10/31/2019, 4:49 PM
in my experience, repositories must not return livedata, your viewmodel validate repository's response and emit into livedata
1
p

pavi2410

10/31/2019, 4:51 PM
Yeah, repository should be only for retrieving data, not observing them
@Somesh You can either do
Copy code
_checkInResponse.value = repository.checkInCheckOutUser(...).value
or
Copy code
_checkInResponse = repository.checkInCheckOutUser(...)
It, basically, is
Copy code
livedata.value = anotherLivedata.value
or
Copy code
livedata = anotherLivedata
b

Bacho Kurtanidze

11/01/2019, 7:00 AM
what if you create mediator live data in view model and set returned liveData from repository as its source somethings like this. I'm facing same problem rn and I cant come up with better idea yet
6 Views