8.0.6: ComboBox.setValue(null) not working after .setItems(...)

Hi,

I’m stuck with a problem with a ComboBox component.

Basically, I’m in a page where a “new project” is being created, and this project is assigned to a “contact”, so I have a ComboBox contactIdWidget listing all possible contacts and, as the last item, a special AContactRecord item showing “New item…”.

When the user clicks “New item…”, the “new project” page is replaced by the “new contact” one. At this point, the user can actually:
a) save the “new contact” page => create a new contact => return to the “new project” page: the new contact reference is passed to contactIdWidget which reloads all the contact records (contactIdWidget.setItems(…)) and selects it (contactIdWidget.setValue(…));
b) cancel the operation => avoid creating another contact => return to the “new project” page: the contactIdWidget reloads all the contact records (contactIdWidget.setItems(…)) and selects nothing (contactIdWidget.setValue(null)).

This mechanism has been working since Vaadin 6.x, then 7.x.
But something broke in 8.x.

Specifically, while point “a” (selecting the newly created contact record) seems ok, point “b” is not: when I return to the “new project” page after aborting a new contact creation, I would expect the contactIdWidget to have nothing selected (.setValue(null)); instead the previously selected record (“New item…”) is selected.

It seems that applying .setValue(null) has no effect just after a .setItems(…).
More, it seems that the last selected value is not cleared.

I tried by forcing a .requestRepaint(), but nothing changed.

Can anyone please confirm what seems to me like a bug? Or maybe show me what’s wrong?

The code is as follows:

    protected void loadContactIdData() {
        AApplicationUi applicationUi = this.getApplicationUi();
        AUser currentUser = applicationUi.getUser();
        AController controller = new AController();
        //
        try {
            LinkedList<AContactRecord> contactRecords = controller.getContactRecordMap(currentUser);
            //
            Long oldContactId = (null == this.contactIdWidget.getValue() ? null : this.contactIdWidget.getValue().getContactId());
            if ((null != oldContactId) && (AValidator.NEW_ID_VALUE.longValue() == oldContactId.longValue())) {
                oldContactId = null;
            }
            //
            this.contactIdWidgetValueChangeListenerRegistration.remove();
            //
            if (currentUser.hasCapability(AUser.Capability.MANAGE_CONTACTS)) {
                contactRecords.add(AContactRecord.getNewItemContactRecord(t("[ New item... ]
")));
            }
            this.contactIdWidget.setItems(contactRecords);
            //
// FIXME: applying .setValue(null) here won't have any effects
            this.contactIdWidget.setValue(null == oldContactId ? null : AContactRecord.getContactRecordByContactId(oldContactId, new LinkedList<AContactRecord>(((ListDataProvider)this.contactIdWidget.getDataProvider()).getItems())));
            //
            this.contactIdWidgetValueChangeListenerRegistration = this.contactIdWidget.addValueChangeListener(this);
        }
        catch (AControllerException exception) { // should not happen
            Notification.show(t(exception.getMessage()), null, Notification.Type.ERROR_MESSAGE);
            this.saveWidget.setEnabled(false);
        }
        catch (AStorageException exception) {
            Notification.show(t(exception.getMessage()), t(exception.getDescription()), Notification.Type.ERROR_MESSAGE);
            this.saveWidget.setEnabled(false);
        }
    }

Thanks,
Marco

I encountered the same issue. The trick is to setValue(null) before setItems. I know that this is kind of weird logic but it works this way.

There are some issues related to that problem


https://github.com/vaadin/framework/issues/9047


https://github.com/vaadin/framework/issues/9566

Thank you so much for pointing me to this bug, it drove me crazy last night and this morning :slight_smile:

Thanks,
Marco

I confirm your solutions actually works, although it breaks the logic of the code a little… let’s wait for a bugfix!

Thanks,
Marco