Architecture-components-samples: How to transform LiveData<ApiResponse<RequestTyp>> to LiveData<Resource<ResultType>>

Created on 21 Jan 2018  路  3Comments  路  Source: android/architecture-components-samples

My use case is only to get data from Network call, No database required and I'm struggling to understand how can i transform from network response type, which is LiveData<ApiResponse<RequestType>> to LiveData<Resource<ResultType>> as required by
success function of Resource class .

I've been tinkering upon the sample, below is the modified version of fetchFromNetwork function
Note: I know i don't have to use MediatorLiveData since there is no more database.

private void fetchFromNetwork(final LiveData<ResultType> dbSource) {
        LiveData<ApiResponse<RequestType>> apiResponse = createCall();
        result.addSource(apiResponse, response -> {
            result.removeSource(apiResponse);
            if (response.isSuccessful()) {

                //  How to send back the received `response` back to caller with `setValue()`
                //      result.addSource(loadFromDb(),
                          // newData -> setValue(Resource.success(newData))) 
            } else {
                onFetchFailed();

            }
        });
    }

Most helpful comment

Hi You can use following code for Network only
~~~
abstract class NetworkOnlyBoundResource @MainThread
internal constructor(private val appExecutors: AppExecutors) {

private val result = MediatorLiveData<Resource<RequestType>>()

init {
    result.value = Resource.loading(null)
    // LiveData<ResultType> dbSource = loadFromDb();

    val apiResponse = createCall()
    // result.addSource(apiResponse, newData -> result.setValue(Resource.loading(newData.body)));
    result.addSource(apiResponse) { response ->

        when (response) {
            is ApiSuccessResponse -> {
                appExecutors.mainThread().execute {
                    // reload from disk whatever we had
                    result.value = Resource.success(response.body)
                    asLiveData()
                }
            }

            is ApiEmptyResponse -> {
                appExecutors.mainThread().execute {
                    // reload from disk whatever we had
                    result.value = Resource.success(null)
                    asLiveData()
                }
            }

            is ApiErrorResponse -> {

                result.value = Resource.error(response.errorMessage, null);
                onFetchFailed()
            }

        }

    }

}


protected fun onFetchFailed() {}

fun asLiveData(): LiveData<Resource<RequestType>> {
    return result
}

@MainThread
protected abstract fun createCall(): LiveData<ApiResponse<RequestType>>

}
~~~

Example
~~~

fun getDestination(): LiveData>> {
return object : NetworkOnlyBoundResource, List>(appExecutors) {
override fun createCall(): LiveData>> {
return githubService.getDestination();
}
}.asLiveData()
}
~~~

if you need java source let me know

All 3 comments

It was simpler than I thought it would be, but it took a while to understand ResultType and RequestType.

Below map operator did the the job were I pull all items off the response to make it ResultType here.

apiResponseLiveData = LiveData>

LiveData<List<Repo>> repoList = Transformations.map(apiResponseLiveData, input -> input.body.getItems()

Hi You can use following code for Network only
~~~
abstract class NetworkOnlyBoundResource @MainThread
internal constructor(private val appExecutors: AppExecutors) {

private val result = MediatorLiveData<Resource<RequestType>>()

init {
    result.value = Resource.loading(null)
    // LiveData<ResultType> dbSource = loadFromDb();

    val apiResponse = createCall()
    // result.addSource(apiResponse, newData -> result.setValue(Resource.loading(newData.body)));
    result.addSource(apiResponse) { response ->

        when (response) {
            is ApiSuccessResponse -> {
                appExecutors.mainThread().execute {
                    // reload from disk whatever we had
                    result.value = Resource.success(response.body)
                    asLiveData()
                }
            }

            is ApiEmptyResponse -> {
                appExecutors.mainThread().execute {
                    // reload from disk whatever we had
                    result.value = Resource.success(null)
                    asLiveData()
                }
            }

            is ApiErrorResponse -> {

                result.value = Resource.error(response.errorMessage, null);
                onFetchFailed()
            }

        }

    }

}


protected fun onFetchFailed() {}

fun asLiveData(): LiveData<Resource<RequestType>> {
    return result
}

@MainThread
protected abstract fun createCall(): LiveData<ApiResponse<RequestType>>

}
~~~

Example
~~~

fun getDestination(): LiveData>> {
return object : NetworkOnlyBoundResource, List>(appExecutors) {
override fun createCall(): LiveData>> {
return githubService.getDestination();
}
}.asLiveData()
}
~~~

if you need java source let me know

Can you give me java code ,please?

Was this page helpful?
0 / 5 - 0 ratings