7

I want to implement pagination to show a chunk of list of my desire item view in my app. That's why I choose to use Google newly released paging library i.e Paging library 3. I use Rxjava, Livedata, and ViewModel in my app. After implementing the paging library, I am facing a weird problem. When I call the method for fetching list, it's calling again and again and not stopped calling the call. In fact, it automatically increases the page number although I did not scroll the list. Here is the code I tried

JobListRestApi.kt

interface JobListRestApi {
    @GET("job/list")
    fun getJobResponse(
        @Query("page") pageNumber: Int
    ): Single<Response<JobResponse>>
}

JobListDataSource.kt

class JobListDataSource @Inject constructor(
    private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
        val position = params.key ?: 1

        return jobListRestApi.getJobResponse(position).toSingle()
            .subscribeOn(Schedulers.io())
            .map { jobResponse -> jobResponse.jobData.jobs }
            .map { jobs -> toLoadResult(jobs, position) }
            .onErrorReturn { LoadResult.Error(it) }
    }

    private fun toLoadResult(data: ArrayList<Job>, position: Int): LoadResult<Int, Job> {
        val prevKey = if (position == 1) null else position-1
        val nextKey = if (position == data.size) null else position+1

        return LoadResult.Page(data, prevKey, nextKey)
    }

}

JobListRepositoryImpl.kt

class JobListRepositoryImpl @Inject constructor(
    private val jobListDataSource: JobListDataSource
): JobListRepository {

    override fun getJobs(): Flowable<PagingData<Job>> {
        return Pager(PagingConfig(pageSize = 20)) {
            jobListDataSource
        }.flowable
    }
}

JobListViewModel.kt

class JobListViewModel @Inject constructor(
    private val jobListRepository: JobListRepository
): BaseViewModel() {

    val jobs: MutableLiveData<PagingData<Job>> = MutableLiveData()

    fun getJobs() {
        if (jobs.value == null) {
            compositeDisposable += jobListRepository.getJobs()
                .subscribe({
                    jobs.value = it
                }, {
                    handleException(it)
                })
        }
    }

}

JobListFragment.kt

class JobListFragment : BaseFragment<JobListViewModel>() {

    private val jobAdapter: JobAdapter by lazy {
        JobAdapter { }
    }

    override fun getLayoutResource() = R.layout.fragment_job_list

    override fun initWidget() {
        job_recycler_view.adapter = jobAdapter
    }

    override fun onResume() {
        super.onResume()
        viewModel.getJobs()
    }

    override fun observeLiveData() {
        observe(viewModel.jobs) {
            jobAdapter.submitData(lifecycle, it)
        }
    }
}

And the output log is https://base-url/job/list?page=1

https://base-url/job/list?page=2

https://base-url/job/list?page=3

https://base-url/job/list?page=4

https://base-url/job/list?page=5

https://base-url/job/list?page=6

https://base-url/job/list?page=7

how can I stop calling serial api unless I go to the last item of the chunk in RecyclerView and scroll the list

Aminul Haque Aome
  • 2,261
  • 21
  • 34
  • I am facing a similar problem, but have checked my API response too. In my case, paging is stuck at Page 2 continuously. Can you please help? – Atish Agrawal Jun 08 '21 at 22:55

2 Answers2

5

You tell Paging there is no more to load by returning null for prevKey and nextKey inLoadResult.Page

Since its infinitely appending, it looks like you never set nextKey to null. Perhaps you meant to check data.isEmpty() instead of key == data.size?

dlam
  • 3,547
  • 17
  • 20
  • thanks for your answer brother. actually The error was in my HttpResponse. I figured it out – Aminul Haque Aome Aug 25 '20 at 11:27
  • I am facing a similar problem, but have checked my API response too. In my case, paging is stuck at Page 2 continuously. Can you please help? – Atish Agrawal Jun 08 '21 at 22:56
  • @AtishAgrawal i am facing the same problem did you solve it? – Mohammad Sommakia Apr 18 '22 at 22:37
  • @MohammadSommakia I did solve it somehow. But I am unable to recall it. It has been a long time now. It was probably an issue with my API Response. – Atish Agrawal Apr 21 '22 at 05:19
  • 1
    For me no it's not an API problem, the library keeps calling the API without stopping and I didn't find out why :( – Mohammad Sommakia Apr 27 '22 at 12:36
  • Paging will automatically continue to load until it fills prefetchDistance or `nextKey == null`, so make sure you are setting that eventually. If you are using RemoteMediator, make sure to also eventually pass `endOfPaginationReached = true`, otherwise Paging will think you haven't reached the end yet! – dlam Apr 28 '22 at 18:01
  • @AtishAgrawal I have the same situation as yours can you help me how you solved it. The api call is stuck at page 2 and is happening continously. – Saneen K P Sep 11 '22 at 21:21
  • @MohammadSommakia did you solve it ? can you please help me. – Saneen K P Sep 11 '22 at 21:22
2

Eventually, I got the error. In fact, the problem was in my Http response Data. The updated DataSource is given bellow

JobListDataSource.kt

class JobListDataSource @Inject constructor(
    private val jobListRestApi: JobListRestApi
): RxPagingSource<Int, Job>() {

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Job>> {
        val position = params.key ?: 1

        return jobListRestApi.getJobResponse(position).toSingle()
            .subscribeOn(Schedulers.io())
            .map { jobResponse -> jobResponse.jobData }
            .map { jobData -> toLoadResult(jobData, position) }
            .onErrorReturn { LoadResult.Error(it) }
    }

    private fun toLoadResult(data: JobData, position: Int): LoadResult<Int, Job> {
        val prevKey = if (position == 1) null else position-1
        val nextKey = if (data.hasMore) position+1 else null

        return LoadResult.Page(data.jobs, prevKey, nextKey)
    }

}
Aminul Haque Aome
  • 2,261
  • 21
  • 34