vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
609 stars 167 forks source link

JS error when removing an element in `beforeClientResponse` #19954

Open sissbruecker opened 2 weeks ago

sissbruecker commented 2 weeks ago

Description of the bug

The scenario is basically:

This results in a JS error like:

Uncaught (in promise) TypeError: this.$server is undefined
    anonymous FlowClient.js line 1049 > Function:3
    anonymous FlowClient.js line 1049 > Function:3
    Ut FlowClient.js:1049
...

The issue seems to be that @ClientCallable schedules a JS call to return the return value of the method to the client:

"execute":[[0,null,null,"return (async function() { this.$server['}p']($0, true, $1)}).apply($2)"]],"timings":[257,2],"syncId":4}]

However, since the element has been removed from the DOM, the JS call results in a null reference.

Expected behavior

There should be no error. Flow should either remove the JS call from the UIDL, or have client-side error handling in case an element reference can not be resolved.

Alternatively, it should not be possible to remove elements from the UI in beforeClientResponse.

Minimal reproducible example

public class TestComponent extends Div {
    public TestComponent() {
        var button = new Button("Remove");
        button.addClickListener(e -> getElement().executeJs("this.$server.remove()"));
        add(button);
    }

    @ClientCallable
    public void remove() {
        UI.getCurrent().beforeClientResponse(this,
                context -> getElement().removeFromParent()
        );
    }
}

Versions