Async Bug: ValueChangeListener gets event from client without user entering anything

public class MainView extends HorizontalLayout {
    CompletableFuture<Void> f;

    public MainView() {
        setSizeFull();

        var field = new BigDecimalField("Field");
        field.setValueChangeMode(ValueChangeMode.EAGER);
        field.addValueChangeListener(event -> {
            System.out.println(event.isFromClient() ? "From Client" : "Not from Client");
        });

        var ui = UI.getCurrent();
        f = CompletableFuture.runAsync(() -> {
            UI.setCurrent(ui);
            ui.getSession().lock();
            ui.getSession().unlock();
            ui.access(() -> {
                field.setValue(BigDecimal.ONE);
            });
        });

        add(field);
    }

}

When I run this, I get the following in the console:

Not from Client
From Client

So I’m getting ValueChangeEvents from the “client” even though I didn’t enter anything in the field with the browser…

I don’t really understand why this is happening, I don’t see anything wrong with the code per se. This breaks my forms, because they mark fields that have been edited by the user as “modified” which is triggered incorrectly here

even this triggers it:

        f = CompletableFuture.runAsync(() -> {
            ui.accessSynchronously(() -> {
                field.setValue(BigDecimal.ONE);
            });
        });

It happens whenever the session is locked and unlocked

But you don’t the issue if you set the value directly? Which Vaadin version are you using? Can you print the old/new values?

v24.0.5

If I just call setValue or do not lock/unlock the session it works fine

no “client” events then

If I change it to System.out.println((event.isFromClient() ? "From Client " : "Not from Client ") + event.getValue());;
It prints

Not from Client 1 
From Client null

Same behavior in Vaadin 23, only on the BigDecimalField (not on the TextField), might be good to create an issue

Is this a bug for flow, or flow-components?

flow-components since it seems to be specific to bigdecimalfield (at least it’s working with the textfield)

https://github.com/vaadin/flow-components/issues/5027

IntegerField seems to have the same behavior

Also NumberField

Yes I was about to say that, all the “numberField”

ComboBox as well

Anyway, we’ll see until someone investigates, its quite a few Components that seem to have this quirk

With ComboBox it seems the value is even not applied at all, it’s reset on the client side to “null” when the event triggers

        var field = new ComboBox<String>("Field");
        field.addValueChangeListener(event -> {
            System.out.println((event.isFromClient() ? "From Client " : "Not from Client ") + event.getValue());
        });
        field.setItems(List.of("asd"));

        var ui = UI.getCurrent();
        f = CompletableFuture.runAsync(() -> {
            ui.accessSynchronously(() -> {
                field.setValue("asd");
            });
        });

        add(field);

weird stuff