5

Problem: I have a Vaadin 8 Grid , and I can't find a way to extract the items inside of it.

Description: Starting from a grid

Grid<Pojo> myGrid = new Grid<>();

I've configured it so it can take data with lazy loading.

    myGrid.setDataProvider(
            (sortOrd, offset, limit) -> dao.getAllFiltered(offset, limit, filter),
            () -> dao.getCountAllFiltered(filter)
    );

At this point, I want to extraxt all the items from the grid (for putting that into an excel), something like List<Pojo> list = myGrid.getItems();. I've also tried passing through myGrid.getDataProvider() , but there are no useful getter into it.

I can't find any getter, how can I achieve this? Thanks

Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
Leviand
  • 2,745
  • 4
  • 29
  • 43
  • 1
    Can you just save a copy of the Items before you add them to the DataProvider? – Jay Jul 12 '18 at 09:50
  • Or just use the data provider directly? – cfrick Jul 12 '18 at 09:51
  • @cfrick , as I said, I can access the data provider, but I can't extract data from it. – Leviand Jul 12 '18 at 10:06
  • @Jay , the data is created dynamically , you mean putting the data somewhere when I call getAllFiltered() ? May works, I try – Leviand Jul 12 '18 at 10:06
  • You can not access the result from `dao.getAllFilttered`? How is this working at all then? – cfrick Jul 12 '18 at 10:07
  • @cfrick it's a Vaadin feature, and it's working perfectly. You can see the logic here -> https://vaadin.com/docs/v8/framework/datamodel/datamodel-providers.html , under the chapter **Lazy Loading Data to a Listing** – Leviand Jul 12 '18 at 10:12
  • @Leviand That's exactly what I mean. Keep a local copy of it in the class when you call your DAO. Then set that List in the DataProvider and just use a standard Getter to get a hold of the List when you want it. – Jay Jul 12 '18 at 10:17
  • 1
    No it's not. You are providing a CallbackDataProvider (implicitly) and your code ther ecalls dao.getAllFiltered(), which is a function in your code. – cfrick Jul 12 '18 at 10:25

3 Answers3

13

Have you tried this basically?

List<Pojo> list = grid.getDataProvider()
                      .fetch(new Query<>())
                      .collect(Collectors.toList());
Leviand
  • 2,745
  • 4
  • 29
  • 43
O. Ozturk
  • 146
  • 1
  • 5
  • public static List getAllItems(DataProvider> dataProvider) { return dataProvider.fetch(new Query<>()).collect(Collectors.toList()); } – Youness Dec 03 '18 at 22:18
4

All DataProvider's implement above mentioned fetch(..) method. I.e. that answer is universal.

Also there are other ways, you can do also:

List<Pojo> list = 
grid.getDataCommunicator.fetchItemsWithRange(0,grid.getDataCommunicator.getDataProviderSize());

see also: Use filtered dataProvider contents when FileDownloader is called in Vaadin

The difference to above mentioned fetch(..) method is that DataCommunicator.fetchItemsWithRange will give the items in the way are currently sorted and filtered in Grid.

In case the DataProvider is instance of ListDataProvider also the following is possible and recommended

ListDataProvider dataProvider = (ListDataProvider) grid.getDataProvider();
List<Pojo> list = dataProvider.getItems();

So there is at least three correct answers to the question. Which is the most suitable depends on the application.

It is good to remind, that using fetch(..) or fetchItemsWithRange(..) to get all the items, from a lazy loading data provider, may result in huge and memory consuming database query (i.e. fetching the whole content). And you probably should not do that. That is why getItems() is implemented only in ListDataProvider, but not included in generic DataProvider interface.

Tatu Lund
  • 9,949
  • 1
  • 12
  • 26
  • Yeah in fact the problem I was facing now was exactly what you said: using fetch uses alot of memory and time. Thanks for your answer – Leviand Jul 14 '18 at 14:57
2

TL;DR: you can't. The grid utilizes the data provider to fetch chunks of data to display (hence the count/limit/offset). The fact that there are eager data source backends (to set the items directly) is just to make it easier for grids with eager data.

So the solution here is to just extract the data from your actual source (your repository etc). So in your case it's something like this:

dao.getAllFiltered(0, dao.getCountAllFiltered(filter), filter)

Or by any means, that make that simpler.

cfrick
  • 35,203
  • 6
  • 56
  • 68