Search code examples
vaadinvaadin-flow

Vaadin 24 - SELECT Component With setItemLabelGenerator not Allowing setEmptySelectionAllowed(true)


I have a simple Select Component that acts a filter and shows a list of Roles (returns the ID of the Role):

private final Select<SJRolesQA> toCcBccFilter = new Select<>();
List<SJRolesQA> allRoles = rolesDataService.findAll();
toCcBccFilter.setItems(allRoles);
toCcBccFilter.setItemLabelGenerator(SJRolesQA::getRole);

Works great - no issues.

What I want to be able to do - is add an empty value (returns null with display of "ALL") so that the user can UNDO the filter. I tried adding:

toCcBccFilter.setEmptySelectionAllowed(true);
toCcBccFilter.setEmptySelectionCaption("ANY");

But I'm getting a NullPointer exception. Here's the error:

java.lang.NullPointerException: null
    at com.vaadin.flow.component.select.Select.updateItem(Select.java:864) ~[vaadin-select-flow-24.1.3.jar:na]
    at com.vaadin.flow.component.select.Select.addEmptySelectionItem(Select.java:965) ~[vaadin-select-flow-24.1.3.jar:na]
    at com.vaadin.flow.component.select.Select.setEmptySelectionAllowed(Select.java:334) ~[vaadin-select-flow-24.1.3.jar:na]
    at edu.sjconfig.views.sjnotifications.SJNotificationsView.setToCcBccSelectValues(SJNotificationsView.java:152) ~[classes/:na]
    at edu.sjconfig.views.sjnotifications.SJNotificationsView.<init>(SJNotificationsView.java:85) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]

Solution

  • The HELPFUL answer from @cfrick helped me to simplify the select. I made the select a simple String (rather than an Object from the database) using a new repository method findAllRollNamesOrderByRole().

    Now the select.setEmptySelectionAllowed(true) and select.setEmptySelectionCaption("ANY") worked great. In my change event listener I can then pass the string value to get the ID using a new repository method getRoleIdByName(roleName).

    Here's the updated code (just FYI):

    private void setNewToCcBccSelectValues(Select select) {
            List<String> allRoles = rolesDataService.findAllRollNamesOrderByRole();
            select.setItems(allRoles);
            select.setEmptySelectionAllowed(true);
            select.setEmptySelectionCaption("ANY");
            
            select.addValueChangeListener((HasValue.ValueChangeEvent e) -> {
                resetBtn.setEnabled(true);
                applyFilterBtn.setEnabled(true);
                String roleName = e.getValue().toString();
                Integer roleId = rolesDataService.getRoleIdByName(roleName);
                System.out.println("Selected Role: " + roleName + "; ID: " + roleId);
            });
        }