1

Currently, I am trying to migrate to the new paging 3 library of Android, but if I see it right, I can't :(

I'm using AWS Amplify as my backend data source and want to include a query into the new load function of the PaginSource class from the paging library.

override suspend fun load(params: LoadParams<String>): LoadResult<String, Car> {
          val query = ListCarsQuery.builder().limit(params.loadSize).build()

          appSyncClient.query(query)
             .responseFetcher(AppSyncResponseFetchers.CACHE_AND_NETWORK)
             .enqueue(
                object : GraphQLCall.Callback<ListCarsQuery.Data>() {
                    override fun onResponse(response: Response<ListCarsQuery.Data>) {
                        val result = CarTransformer.toModels(response)
                        // Here is my actual result list
                    }

                    override fun onFailure(e: ApolloException) {
                        TODO("Not yet implemented")
                    }
                }
        )

          //How can I add my result list here ? 
          return LoadResult.Page(
             data = listOf(),
             prevKey = null,
             nextKey = ""
            )

since the method enqueues gives me a void back I don't know how I could wait on it or trigger a callback like in paging library 2. In paging 2 I had the option to call the callback.onResult(result.data, result.nextLink) method in the enqueue().onResponse function without having to give anything back.

Is there a way to achieve it or should I stick with paging 2?

Ahmet K
  • 713
  • 18
  • 42
  • Stick with Paging 2. I've had the unfortunate decision to go with 3 and I am now fighting a lot with it just to do simple things that were easy to do in 2. Not only that, but the documentation is for some reason relying heavily on usages with Retrofit with no example on how to do the same without Retrofit. It's really bad at the moment and needs a lot more work before solid adoption. – Shadow Nov 16 '20 at 04:46

2 Answers2

3

Paging3 doesn't offer a callback API (yet), so you would need to wrap it into an RxJava Single, a Guava ListenableFuture, or into a suspending Kotlin coroutine.

Rx version of PagingSource is available in paging-rxjava2/3 artifacts, and Guava's is in paging-guava.

In terms of the actual conversion, it would be a lot to list all the possibilities, but for example there are Kotlin Coroutine builders that allow you to wrap and await xallbacks in a suspending context. See suspendCancellableCoroutine as an example, you basically get a Continuation object you can call resume(result) on.

dlam
  • 3,547
  • 17
  • 20
  • can you please take a look at [this](https://stackoverflow.com/questions/75225455/paging-3-use-network-data-as-primary-source-and-local-data-as-addition) question? I know I shouldn't do that but I'm really frustrated and know that you are experienced in paging3 topics – Ahmet K Jan 26 '23 at 08:42
0

As @dlam mention, you can use suspendCacellableCoroutine or suspendCoroutine as follows:

Using your example it would be:

override suspend fun load(params: LoadParams<String>): LoadResult<String, Car> {

    return suspendCoroutine { continuation ->
        val query = ListCarsQuery.builder().limit(params.loadSize).build()

        appSyncClient.query(query)
                .responseFetcher(AppSyncResponseFetchers.CACHE_AND_NETWORK)
                .enqueue( object : GraphQLCall.Callback<ListCarsQuery.Data>() {
                            override fun onResponse(response: Response<ListCarsQuery.Data>) {
                                val result = CarTransformer.toModels(response)
                                //Here is where you use your continuation object in order to resume the suspended function
                                continuation.resume(LoadResult.Page(
                                        data = result,
                                        prevKey = null,
                                        nextKey = ""
                                ))
                            }

                            override fun onFailure(e: ApolloException) {
                                TODO("Not yet implemented")
                                continuation.resume(LoadResult.Error(e))
                            }
                        }
                )
    }
}
Mr.O
  • 813
  • 7
  • 14