2

I was wondering can I use paging3 library for API's that does not support 'page=RANDOM_NUMBER' in their queries? For example I have an API in which I can add custom query like 'number=50' and it will display 50 items as a result. I'm confused that I wouldn't be able to use that library for my API without page=RANDOM_NUMBER query. Can someone give me an answer?

StefanJo
  • 275
  • 3
  • 13

1 Answers1

3

Paging3 supports arbitrary key types (you define both the key and how it is used). In order to load data incrementally, you need to be able specify "load after ___", otherwise it's not possible to continue loading data after the initial load. If this is something that is tracked independently, say a cookie or session token, then you can try keeping maxSize set to unbounded, and just use any non-null value for nextKey.

Edit: Since you mentioned you are in the item-keyed scenario, where your next load is based on the last item you loaded, you might do something like this:

class MyPagingSource : PagingSource<String, Item>(
  val api: NetworkApi,
) {
  override suspend fun load(params: LoadParams): LoadResult<String, Item> {
    try {
      val result = withContext(Dispatchers.IO) {
         api.loadPage(after_id = params.key)
      }

      return LoadResult.Page(
        data = result.items,
        nextKey = result.items.lastOrNull().id,
      )
    } catch (exception: IOException) {
      return LoadResult.Error(exception)
    }
  }
}

Basically whatever value you pass to nextKey will get passed to LoadParams.key when user near the bottom of the loaded data, and in the case where there are no more items or you get an empty response from network (Due to being at the end of the list), you can return null for nextKey to tell Paging there is no more to load in that direction.

Note that I haven't covered prepend / prevKey, but if it is unsupported in your case you can just pass null.

If you don't support prepend, you won't be able to resume loading from the middle of the list, so you need to return null in getRefreshKey() which tells Paging what key to use to resume loading from a scroll position in case of config change, etc.

dlam
  • 3,547
  • 17
  • 20
  • can you provide a solid example or any reference? I understand the concept but it's hard to implement in code – Teo Sep 06 '21 at 07:33
  • Well it depends on your API, after you query the first 50 items, how do you query the next 50? – dlam Sep 09 '21 at 02:12
  • the api is queired by `after_id` which get the "id" from the last item's id. By using `after_id`, the query will return some sort of "next page" data. – Teo Sep 09 '21 at 02:39
  • In this case you're in the item-keyed scenario where you want to load a page based on a string that is computed per-item. I've updated my answer to include a toy example, but essentially you control the whole flow in Paging - what value to send for the next load, and also how to parse that value. – dlam Sep 09 '21 at 02:49
  • I think there will be a variable to store `after_id`, initially `after_id` would be null, so the api return page 1's data and `after_id` would store last item's id from api result. After scrolling down, the api called with `after_id` to get page 2's data. Is the overall idea like this? – Teo Sep 09 '21 at 02:54
  • The result you return from `PagingSource.load()` includes a property that tells the Paging library what to pass for `LoadParams.key` on the next load. You don't need any other additional variable to track it yourself. – dlam Sep 09 '21 at 20:31