Suspected issue with Pagination using additional data store

Hi support,
I am using an additional datastore to get my data from a restful service. I have a browse list of Item entities. The data is displaying the records from my restful service fine. The problem I am having is the pagination- it only shows all the records on one page. I cannot navigate from one page to another because only one page is accessible. However, the rows per page is working as expected to display the number of rows I want. See the image below:

When I compare using the project with main store (database), the pagination works fine.
Could it be that pagination does not work for additional datastore?

Thanks

image

Hi,
You need to write paging implementation inside your custom datastore. The io.jmix.core.LoadContext.Query contains this information. After getting the firstResult and maxResults field values you’ll need to invoke your external service and get only required number of records from there.

Hi Maxim,
Thanks for your assistance as usual. I have tried what you suggested. Now the next, previous button of the pagination is clickable. However, it still does not move to the next page. The pagination does not navigate to the next list of records.

Thanks

image

Hi,
Just adding more details to my question. I realize that the pagination is not numbered and the navigation is not triggering the loader. I am also having this error below

> Pagination component receives loader’s first result (0) that is out of last page range. Component may work incorrectly

Let me share the controller code behind if it will help:


 > @Install(to = "businessPartnersDl", target = Target.DATA_LOADER)
>     private List<BusinessPartner> itemsDlLoadDelegate(LoadContext<BusinessPartner> loadContext) {
>         //int firstResult = loadContext.getQuery().getFirstResult();
>         //int maxResult = loadContext.getQuery().getMaxResults();
>         return dataManager.loadList(loadContext);
>     }
> 
>     @Install(to = "pagination", subject = "totalCountDelegate")
>     private Integer paginationTotalCountDelegate() {
>         //return dataManager.load(BusinessPartner.class).all().list().size();
>         var s = businessPartnersDl.createLoadContext();
>         return (int)dataManager.getCount(s);
>     }

The custom datastore manages the DataManager which in turn calls my restful services

>  @Override
>     public List<Object> loadList(LoadContext<?> context) {
>         return new ArrayList<>(businessPartnerService.loadCustomers(context));
>     }
> 
>     @Override
>     public long getCount(LoadContext<?> context) {
>         return context.getQuery().getMaxResults()-context.getQuery().getFirstResult();
>     }

Hope this helps to paint the picture clearer.

Thanks in advance

image

There is no reason to have delegates in the screen controller. Try to remove them - in this case all requests should anyway come to the data store implementation.
Also, it seems that the long getCount() method in the data store should return the total count of all records.

Hi Maxim,
Thanks for your response. I have removed all the screen controller. All requests are going to the data store implementation which in turn calls my REST services calls. The getCount() is returning the size().
However, the pagination is not splitting into pages yet. The next and previous buttons are all grayed out. They are not clickable. All the records are pulling in one page no matter Rows per page number I choose. What could be wrong with my implementation?

Thanks in advance.

If all records are displayed then it probably means that your businessPartnerService.loadCustomers(context) doesn’t take the paging information into account and always returns all records received from the REST service.

Hi Maxim,
It is sorted. Thanks for your assistance.

I modified the getCount() to return all records and I also worked on the businessPartnerService to take the paging information into account.

Best regards

Hi Olumide Omolayo,
I have a task with this issue, can you share to me how to call REST API and set data to collection and use pagination with it.

Regards.

Hi Le Duy,

To call REST API, check the below Jmix documentation. You need to use additional data store as your data model

Data Stores :: Jmix Documentation

Then, follow the above recommended answers above.

Let me know if this satisfies you or make clearer your question.

Hi Olumide Omolayo,
i call api and set data to dataContainer. i used pagination for this dataContainer and it’s not working.
so how to fix it, pls.

image
image
image
image

Hi Le Duy,
I think the problem with your code is that you are putting the pagination in the wrong place.
Your pagination should be within the layout, not within the data.
See example below:
Also, check the documentation about pagination

https://docs.jmix.io/1.x/jmix/1.5/ui/vcl/components/pagination.html

 <layout expand="itemGroupsTable" spacing="true">
        <pagination id="pagination"
                    itemsPerPageVisible="true"
                    itemsPerPageOptions="10,20,50,100">
            <loaderProvider loaderId="itemGroupsDl"/>
           </pagination>
           <table id="itemGroupsTable"
                              width="100%"
                              dataContainer="itemGroupsDc">
                      <actions>
                          <action id="create" type="create" enable="false"/>
                          <action id="edit" type="edit" enable="false"/>
                          <action id="remove" type="remove" enable="false"/>
                      </actions>
                      <columns>
                          <column id="code"/>
                          <column id="name"/>
                      </columns>
                      <buttonsPanel id="buttonsPanel"
                                    alwaysVisible="true">
                          <button id="createBtn" action="itemGroupsTable.create"/>
                          <button id="editBtn" action="itemGroupsTable.edit"/>
                          <button id="removeBtn" action="itemGroupsTable.remove"/>
                      </buttonsPanel>
                  </table>
                  <hbox id="lookupActions" spacing="true" visible="false">
                      <button action="lookupSelectAction"/>
                      <button action="lookupCancelAction"/>
                  </hbox>
              </layout>

Hi Olumiede Omolayo,
this is my collection
image

and this is my pagination
image

i call api and set data to collection
image

my pagination still not working.
image

so do u have solution for this?

Regards.

Hi,
I have had this same issue before while I was starting to learn how pagination works. The reason you are having the pagination on one page is because you are not setting the total count.

For example, let say your rest api service is returning scorecard of 100 records but you want to page 20 records per page. You need to return the total count of records in this case 100 along side the result you are getting from your service.

Check all Maxim’s answers above. It should guide you.

If you are using additional datastore as I told you earlier, you should have something like this: Data Stores :: Jmix Documentation

Watch the getCount method. It should return the total count of records expected (e.g. 100)

public class BPDataStore implements DataStore {
    private String name;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Nullable
    @Override
    public Object load(LoadContext<?> context) {
        return null;
    }

    @Override
    public List<Object> loadList(LoadContext<?> context) {
       return null;
    }

    @Override
    public long getCount(LoadContext<?> context) {
        return 0;
    }

    @Override
    public long getCount(ValueLoadContext context) {
        return 0;
    }

    @Override
    public Set<?> save(SaveContext context) {
        return null;
    }

    @Override
    public List<KeyValueEntity> loadValues(ValueLoadContext context)  {
        return null;
    }