0

Select element bound to a state object loses update binding.

I am doing some exploration with lit-html and various routing/store combinations and have come across this strange behaviour. I have used the create-lit-app stackblitz.

I have a menu which is populated from an array on the store.state object. These links update a currentPage attribute on the store.

The navigation is self listens to the store and sets an [active] attribute if it matchs the store's currentPage.

Click events update the store. This is all working fine.

In another element (hello-world) I have a select box. The select box is populated by the same array on the store.state object. The [selected] attribute is set if the option matches the currentPage attribute. This also works fine.

I also put a couple of p tags which display the currentPage for sanity... or insanity... not yet sure.

Now, when I go back to using the menu the state changes and the menu [active] is working, as are the p tag updates in the other (hello-world) element. The select element however does not update. I can use the select to update the state but the binding down to the select seems to have stopped working all together.

I have tried super.update() and this.update() after googling similar issues but still no cheese. I am wondering if it is a function of an ugly anti-pattern on my part or if this might be an RC bug.

class HelloWorld extends LitElement {

constructor() {
    super();
    store.subscribe(() => super.update());
}

_updatePage(e) {
  console.log(e.target.value);
  store.update(s => s.currentPage = e.target.value);
}

render() {

    return html`
  <p class="app-intro">
    Current page: ${store.state.currentPage}
  </p>
  <select @change=${(e) => this._updatePage(e)}>
    ${store.state.navItems.map(navItem => {
      return html`<option ?selected=${store.state.currentPage===navItem.page}>${navItem.page}</option>`
      })
    }
  </select>

        <p class="app-intro">
            Current page: ${store.state.currentPage}
        </p>
    `;
}

}

I want to be able to update the state from anywhere in the app and have all subscribers updated.

Jeremy
  • 11
  • 1
  • 5

1 Answers1

1

My suggestion is to set properties on your element when the store updates, that way your element is not tightly coupled to the store's structure.

Otherwise, you can use this.requestUpdate() to trigger an update. update() is just a lifecycle callback which is called by LitElement internally.