1

I'm implementing the paging library 2.1.2 in my Android app, my DataSource class looks like this

public class TransactionsDataSource extends PageKeyedDataSource<Integer, Items> {


private static final int FIRST_PAGE = 1;
private Context context;
private Repository repository;
private String bearerToken;
private int merchantId;


public TransactionsDataSource(Context context, int merchantId) {
    this.context = context;
    this.merchantId = merchantId;
    repository = new Repository();
    repository.initLoginSharedPref(context);
    bearerToken = repository.getAccessToken();
}


@Override
public void loadInitial(@NonNull PageKeyedDataSource.LoadInitialParams<Integer> params, @NonNull PageKeyedDataSource.LoadInitialCallback<Integer, Items> callback) {


    ApiClient.getApiClient().getApiInterface().getMerchantTransactions(bearerToken,
            merchantId, FIRST_PAGE)
            .enqueue(new Callback<MainResponse>() {
                @Override
                public void onResponse(Call<MainResponse> call, Response<MainResponse> response) {
                    if (response.body() != null){

                        int code = response.body().getCode();
                        if (code == SERVER_OK_CODE){
                            callback.onResult(response.body().getData().getItems(), null, FIRST_PAGE + 1);
                        } else if (code == SERVER_UNAUTHENTICATED_CODE){

                            repository.clearCache();
                            HelperMethods.signOut(context);
                        } else {
                            //no more data to load
                        }


                    }
                }

                @Override
                public void onFailure(Call<MainResponse> call, Throwable t) {

                }
            });
}

@Override
public void loadBefore(@NonNull PageKeyedDataSource.LoadParams<Integer> params, @NonNull PageKeyedDataSource.LoadCallback<Integer, Items> callback) {

}

@Override
public void loadAfter(@NonNull PageKeyedDataSource.LoadParams<Integer> params, @NonNull PageKeyedDataSource.LoadCallback<Integer, Items> callback) {


    ApiClient.getApiClient().getApiInterface().getMerchantTransactions(bearerToken,
            merchantId, params.key)
            .enqueue(new Callback<MainResponse>() {
                @Override
                public void onResponse(Call<MainResponse> call, Response<MainResponse> response) {
                    if (response.body() != null){

                        int code = response.body().getCode();
                        if (code == SERVER_OK_CODE){

                            Integer key = params.key + 1;
                            callback.onResult(response.body().getData().getItems(), key);

                        } else if (code == SERVER_UNAUTHENTICATED_CODE){

                            repository.clearCache();
                            HelperMethods.signOut(context);
                        } else {
                            //no more data to load
                        }

                    }
                }

                @Override
                public void onFailure(Call<MainResponse> call, Throwable t) {

                }
            });
}

}

As per my knowledge the loadInitial() method is reponsible for loading the first page of data and then loadAfter() will be triggered after that to load the rest of the pages while the key is incremented by one until there's no more data to be loaded. But when I debug the app the loadAfter() is continously repeat loading the first page only even I make sure to increment the params.key() by 1. I even tried to hard code the page number as following but still loading the first page only

ApiClient.getApiClient().getApiInterface().getMerchantTransactions(bearerToken,
        merchantId, 2)

I need to know what's happening and how to fix this bug?

Michael
  • 411
  • 2
  • 6
  • 15
  • Just out of curiosity, is there any reason why you are using the paging 2.x APIs? Most of the api surface there has been deprecated in the latest stable version of paging. – dlam Sep 21 '21 at 18:32
  • I would also ask, could you post what the HTTP calls you make and responses you get back are? Is it possible that your backend returns the previous page if you request a page that doesn't exist? E.g., there's only 1 page of data? One issue I immediately see in your code is that you never terminate (pass null to nextKey) to `PageKeyedDataSource.LoadCallback`. – dlam Sep 21 '21 at 19:36
  • @dlam let me clarify to you, 1- during debugging I made sure that the loadAfter calls the first page from API while on PostMan the API works perfectly. 2- you say my code never terminate which is not true because there's an if condition where I check if (code == SERVER_UNAUTHENTICATED_CODE) which means the response carries new data, else it will terminate – Michael Sep 27 '21 at 19:27
  • I mean that you should communicate to paging that a page is terminal (the last page) by returning null for nextKey, or it will continue to try to load in that direction. – dlam Sep 28 '21 at 00:30

1 Answers1

0

Although my implementation is 100% correct and After I tried so many things finally I got my way to solve this weird behavior. I made a small change in my interface instead of passing the page number to getMerchantTransactions() I decided to send the whole url as a parameter and it worked fine here's my method in interface after update

@POST
@FormUrlEncoded
Call<MainResponse> getMerchantTransactions(@Header("Authorization") String bearerToken,
                                           @Field("id") int merchantId,
                                           @Url String url);

And then calling this method in loadInitial() and loadAfter() like this

ApiClient.getApiClient().getApiInterface().getMerchantTransactions(bearerToken,
            merchantId, "myUrl?pagenumber=" + params.key)
Michael
  • 411
  • 2
  • 6
  • 15