How to observe property changes with LitElement

I personally override the "requestUpdate" method to be aware of a change before rendering.

My use-case is to intercept a change of a "label" attribute to trigger asynchronous data request.

Snippet below (in TypeScript):

@customElement('my-element')
export default class MyElement extends LitElement {

    @property({type: String})
    label: string | null = null;

    @property({attribute: false})
    private isLoading: boolean = false;

    @property({attribute: false, noAccessor: true})
    private data: MyData | null = null;

    protected render() {/*some code*/}

    requestUpdate(name?: PropertyKey, oldValue?: unknown) {
        if(name && name == "label" && this.label !== oldValue) {
            this.isLoading = true;
            requestData(this.label, this._callbackData);
        }
        return super.requestUpdate(name, oldValue);
    }

    private _callbackData(data: MyData}) {
        this.data = data;
        this.isLoading = false;
    }

}

In this way, my element is rendered only twice: one with the new label and loading as true then one other when data are available.


Version 0.6.0+

First, you have to specify element properties. You can do it by creating a static getter which returns an object including their names as keys and their attribute related configuration.

The updated lifecycle method will be called when changed properties had caused a re-render. The first argument will return values before an update.

class MyComponent extends LitElement {
  static get properties() {
    return {
      foo: {}
    };
  }

  constructor() {
    super();
    this.foo = 0;
    setInterval(() => this.foo++, 1000);
  }

  updated(changedProperties) {
    console.log(changedProperties); // logs previous values
    console.log(this.foo); // logs current value
  }

  render() {
    return html`${this.foo}`;
  }
}

customElements.define("my-component", MyComponent);