7

I have an existing REST service that accepts PAGE and SIZE parameters

/fetchrecords?page=0&size=10

which in turn, creates a Spring Pageable to be used with Spring Repository.

Pageable pageRequest = new PageRequest(page, size, Sort.Direction.DESC, "created");

I want to now use Vaadin 8 CallbackDataProvider, however it produces OFFSET and LIMIT to be used for the BackendDataProvider.

dataProvider = new CallbackDataProvider<MyPojo, Void>(
                    query -> service.fetchrecords(query.getOffset(), query.getLimit()).stream(),
                    query -> service.getCount());

Of course this won't work as offset != page, and limit value will change based on how many records are left, according to the offset position.

Without rewriting the rest/service, how can I go from the DataProvider OFFSET and LIMIT to PAGE and SIZE, correctly?

Cœur
  • 37,241
  • 25
  • 195
  • 267
steve
  • 1,786
  • 1
  • 15
  • 29
  • 1
    Just subtract offset from limit (this gives you pageSize) and then you can divide offset by pageSize (page) – ByeBye Aug 09 '17 at 07:02
  • @ByeBye what if the offset is not exactly at the start of the page? – Steffen Harbich Aug 09 '17 at 09:15
  • @ByeBye Vaadin DataProvider will always change the limit and offset when you scroll through the component (grid), so I suspect it is not reliable to base a direct page/size off of. – steve Aug 09 '17 at 18:38

2 Answers2

4

I had the same problem. The Vaadin paging with offset and limit is more powerful than paging with page and page size (as in your REST service and in spring class PageRequest). So, the answer to your question is: you can't easily. If you could change your REST service parameters to offset and limit then you can implement your own Pageable like:

public class Range implements Pageable, Serializable {

    private static final long serialVersionUID = 0L;

    private int limit;
    private long offset;
    private Sort sort;

    public Range(long offset, int limit, Sort sort) {
         ...
    }

    @Override
    public long getOffset() {
        return offset;
    }

    ...

}

I wonder why this isn't available out-of-the-box.

Another option is to map the offset/limit to possibly multiple pages that include the required range of data, then get these pages and take only the necessary data.

Please note: This is not working for the last page requested by Vaadin when accessing Neo4j via Spring Data Neo4j. SDN v5.2.8 will use the following code to apply "skip" to query

parameters.put(SKIP, pageable.getPageNumber() * pageable.getPageSize());

The use of getPageNumber is a problem, e.g. offset 100 and limit 23 results in skip of 92. Filed an issue.

Steffen Harbich
  • 2,639
  • 2
  • 37
  • 71
  • 3
    You can find a full working example of pageable implementation [here](https://stackoverflow.com/a/36365522/474287) – Morfic Aug 09 '17 at 09:53
  • @forfic , thanks. I did come across the Custom Pageable, however I was trying to go away from modifying my service as everything else uses Page, Size currently. If there are no other options, I will have to support offset and limit in my api/service – steve Aug 09 '17 at 18:36
  • 1
    As I mentioned the other option is to map the offset/limit range to multiple pages, retrieve them and then take only the data you need. Of course this is somehow a waste of resources :) – Steffen Harbich Aug 10 '17 at 06:11
0

You can use Spring Data Provider Add-on.

https://vaadin.com/directory/component/spring-data-provider-add-on