Grid: Unable to grid for configured number of columns (dynamic columns) than entity bound columns (fixed colums)

Vaadin has been impressive for static and dynamic contents. The grids require an entity to be bound to them so the entity fields are rendered as grid columns. I am exploring a use case in which the entity has columns of type List.

class Candidate {

     Integer id;
     String name;
     Map<String, String> socialMediaUsernameAndUrls;

}

if there is a config loaded in to above pojo Candidate


application.user[0].id=1
application.user[0].name=dev1
application.user[0].socialMediaUsernameAndUrls={github: 'jack', linkedin: 'jacklin', x: 'jackx'}

application.user[1].id=2
application.user[1].name=dev2
application.user[0].socialMediaUsernameAndUrls={github: 'jim', linkedin: 'jimlin', x: 'jamx'}

application.user[2].id=3
application.user[2].name=dev3
application.user[0].socialMediaUsernameAndUrls={github: 'Kim', linkedin: 'kimlin', x: 'kimx'}


the idea is to render grid as following, (candidates followers on various platforms )

Id Name Github LinkedIn X
1 name 3241 45 23
2 February 2342 22k 32k
3 March 765 555 54

but while adding columns to grid in following way.


socialMediaUsernameAndUrls.forEach((socialMedia, username) -> grid.addColumn(socialMedia) );

I am getting following error,


There was an exception while trying to navigate to '' with the root cause 'java.lang.IllegalArgumentException: Can't resolve property name 'GitHub' from 'Property set for bean com.pkg.Candidate'


I believe this is because, the ‘github’ isn’t a candidate property, it’s coming from the map inside the entity. Does that mean the grid here can only work for static (fixed) columns that are present in the entity and custom columns (dynamic columns) cannot be added?

The addColumn() method has many overloads. The one you used takes as input a property name that should match a bean property.
But you can for example create a column that takes a ValueProvider to dinamically compute values based on the bean instance.

For example

socialMediaUsernameAndUrls.forEach((socialMedia, username) ->
    grid.addColumn(candidate -> 
        candidate.socialMediaUsernameAndUrls.get(socialMedia)
    ).setHeader(socialMedia)
);

Look at Grid Javadocs for additional information

1 Like

Thank you @marcoc_753 .

The ValueProvider based overloaded addColumn method worked. Not exactly how it is mentioned above as username was not required in the table.

Posting what worked for me so that other can relate what was needed for the use case.

socialMediaUsernameAndUrls.forEach((socialMedia, username) ->
    grid.addColumn(candidate -> 
        
         retrieveFollowerCount( socialMedia, candidate.socialMediaUsernameAndUrls.get(socialMedia) ) 
       
    ).setHeader(socialMedia)
);

where retrieveFollowerCount method is as following

Long retrieveFollowerCount(String socialMedia, String username){
    // implementation to fetch follower count from social media for given username
}

1 Like

Here is a live demo and full code example of Grid with HashMap type How do I use HashMap in Grid and Binder instead of POJO - Vaadin Cookbook

1 Like