Search code examples
javascriptcustom-element

Why is attributeChangedCallback not executed even though an attribute is set on a custom element?


I have included the important part of the code. The localStorage variable is already set to a username, so this.username is not null, and the attribute is successfully set.

My problem is that attributeChangedCallback is never executed.

Is it because I set the attribute in the constructor, or do I have a typo somewhere?

customElements.define('chat-app', class extends HTMLElement {
  constructor () {
    super()
    this.attachShadow({ mode: 'open' })
    this.username = localStorage.getItem('username')
    this.setAttribute('username', this.username)
  }

  static get observedAttributes() {
    return [ 'username' ]
  }

  attributeChangedCallback (name, oldValue, newValue) {
    console.log('Username was set.')
  }
})

Solution

  • I think this is related to the upgrade procedure. The events are "manually" called before calling the constructor, using the current attributes state.

    However, I couldn't find anything about how these events are processed during construction. I'd assume they work like hooks and are attached outside of the constructor (hence why it wouldn't execute for changes made in the constructor).

    Something in the standard that hints at this englobing system is how attribute changes are applied: with it queuing a seemingly global mutation record, as well as a custom element callback reaction.

    Therefore I'd assume you can't automatically detect attribute changes from within the constructor.