bug in validation

The UI contains a DatePicker whose value determines the content of every other component. Thus, when the date changes, a field may be set to valid value or cleared if the database contains no record. If a field is cleared as a result of changing the date, the user is presented with a failed validation message before the user has even had the opportunity to enter something as if the user has already done something wrong (as shown in the attachment). In an effort to get around this design, I added a condition at the beginning of the validator method. It’s those few lines of code that result in the null pointer exception from the clear method. Without those lines in the validator method, no null pointer is thrown, but you’re stuck with an inappropriate - from the user’s perspective - error message.

At any rate, calling clear on a non-null component shouldn’t result in a null pointer exception.

 EnterResultsView() {
        time = new TextField("Time");
        time.setRequiredIndicatorVisible(true);
        time.addValueChangeListener(e -> handleInputValueChange());
        binder.forField(time).withValidator(this::timeValidator, "Invalid value").withConverter(new TimeConverter()).bind(Result::getTime, Result::setTime);
 private void handleDateChange(HasValue.ValueChangeEvent e) {
        LocalDate date = (LocalDate)e.getValue();
        clearUserInputs(); //line 149
  private void clearUserInputs() {
        isClearInputs = true;
        time.clear(); //line 215
java.lang.NullPointerException: null
	at com.vaadin.flow.data.binder.ValidationResultWrap.isError(ValidationResultWrap.java:86) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.BindingValidationStatus.<init>(BindingValidationStatus.java:98) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$BindingImpl.toValidationStatus(Binder.java:1081) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$BindingImpl.doValidation(Binder.java:1092) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$BindingImpl.validate(Binder.java:1035) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$Binding.validate(Binder.java:135) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder.handleFieldValueChange(Binder.java:1453) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$BindingImpl.handleFieldValueChange(Binder.java:1165) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.data.binder.Binder$BindingImpl.lambda$new$f9b94f89$1(Binder.java:1003) ~[flow-data-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.internal.AbstractFieldSupport.lambda$addValueChangeListener$828eca10$1(AbstractFieldSupport.java:96) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.ComponentEventBus.fireEvent(ComponentEventBus.java:194) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.Component.fireEvent(Component.java:359) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.ComponentUtil.fireEvent(ComponentUtil.java:386) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.internal.AbstractFieldSupport.setValue(AbstractFieldSupport.java:207) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.internal.AbstractFieldSupport.setValue(AbstractFieldSupport.java:133) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.AbstractField.setValue(AbstractField.java:181) ~[flow-server-2.1.9.jar:2.1.9]

	at com.vaadin.flow.component.textfield.TextField.setValue(TextField.java:441) ~[vaadin-text-field-flow-2.1.1.jar:na]

	at com.vaadin.flow.component.textfield.TextField.setValue(TextField.java:32) ~[vaadin-text-field-flow-2.1.1.jar:na]

	at com.vaadin.flow.component.HasValue.clear(HasValue.java:179) ~[flow-server-2.1.9.jar:2.1.9]

	at com.wodiq.ui.views.EnterResultsView.clearUserInputs(EnterResultsView.java:215)
	at com.wodiq.ui.views.EnterResultsView.handleDateChange(EnterResultsView.java:149)
private boolean timeValidator(String time) {
        if (isClearInputs) {
            isClearInputs = false;
            return true;
        }

I can get around the null pointer and also get the behavior that I want by doing this, but I shouldn’t have to.

private void clearUserInputs() {
        timeBinding.unbind();
        time.clear();
        timeBinding = binder.forField(time).withValidator(this::timeValidator, "Invalid value").withConverter(new TimeConverter()).bind(Result::getTime, Result::setTime);

18273523.png

At any rate, calling clear on a non-null component shouldn’t result in a null pointer exception.

It doesn’t. The bug comes from the binder not the text field.

Please file a bug here: https://github.com/vaadin/flow/issues