3

I have a problem with reading property in my webcomponent. I don't understand why it's not working. I create simple example and after click the button I should get value of property but it's null. I don't know why ? In my others test, setProperty works OK, but then getProperty always get same value what I set in setProperty. I also try change property in a browser. PropertyChangeListener also is never triggered after change value on client side. Spend a lot time for this. Can somebody tell me what's happening?

HelloWorld.class

import com.vaadin.flow.component.DomEvent;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.littemplate.LitTemplate;

@Tag("hello-world")
@JsModule("./components/hello-world.ts")
public class HelloWorld extends LitTemplate {
    @DomEvent("click")
    public static class ClickEvent extends ComponentEvent<HelloWorld> {
        public ClickEvent(HelloWorld source, boolean fromClient) {
            super(source, fromClient);
        }
    }

    public HelloWorld() {
        setId("hello-world");
        getElement().addPropertyChangeListener("value", "change", e -> {
            System.out.println("change value: " + e.getValue());
        });
        addListener(ClickEvent.class, e -> System.out.println("getValue(): " + getValue()));
    }
    public void setValue(String value) {
        getElement().setProperty("value", value);
    }

    public String getValue() {
        return getElement().getProperty("value");
    }
}

hello-world.ts

import { LitElement, html, property} from 'lit-element';

export class HelloWorld extends LitElement {
    @property({type: String}) value = 'unset';

    render() {
        return html`
            <div>${this.value}</div>
            <button @click=${this._click}>Button</button>
        `;
    }

    _click() {
        this.value = 'Clicked';
        let click = new Event('click');
        this.dispatchEvent(click);
    }
}
customElements.define("hello-world", HelloWorld);

1 Answers1

3

You have set up the property value to be synchronized back to the server when a change event is fired in the client, but no such event is fired. There is, however, a click event so you might want to change addPropertyChangeListener to use that DOM event name instead.

Leif Åstrand
  • 7,820
  • 13
  • 19
  • I don't understand this. I should have dispatchEvent to server every time when property 'value' has change on client side ? For example I generated image on client side, but no always I need this data. – Dariusz Jagodzik Jun 21 '21 at 10:25
  • The server has no way of directly monitoring the client-side property. It's up to you to trigger it to check if the value has changed. You do that by defining a DOM event that should be used as a trigger. Whenever a DOM event with that name is dispatched for the element (programmatically or through user action for a native event), then Flow will check the property value and send it to the server in case it's different than the last know server-side value. – Leif Åstrand Jun 21 '21 at 11:08
  • OK, I get this, but I think it's not very optimal solution for my case. I wrong understand how and for is it: `addPropertyChangeListener`. I think should better name for `addPropertyChangeListener` - missing in name of method information about it's for synchronization between client side to server side. I read the documentation but there is very simple example. In my real case I need read value from my component after click on button outside my component. – Dariusz Jagodzik Jun 21 '21 at 11:21