Skip to content

Consider auto-initializing if “render()” is called before initialization. #334

@theengineear

Description

@theengineear

The following code will not do what you want:

class MyElement extends XElement {
  static get properties() {
    return {
      message: { type: String, default: 'default message' },
    };
  }

  static get template(html) {
    return ({ message }) {
      return html`${message}`;
    }
  }
}
customElements.define('my-element', MyElement);

/* … */

const element = document.createElement('my-element');
element.render();
assert(element.textContent === 'default message');

You’re meant to actually call something like document.body.append(element) such that connectedCallback is called†. By calling render() prematurely like this, you will get a properties bag which is likely all undefined and importantly you are not guaranteed that initial / default values exist! It’s this last part that is so problematic.

† Yes, you can manually call connectedCallback() to initialize… which is… basically fine, but not something which we say we officially support.

Option 1

I think we should consider throwing hard within render() if we detect that we have not yet been initialized. The element is not meant to be used this way and it’s only really a mistake that you can call render() like this.

Related — if we really wanted to lock this down, we could perform a sanity check within connectedCallback to see if we are indeed attached and again throw hard if we are not (i.e., if an integrator called element.connectedCallback() manually).

Option 2

Give the users what they want… we could initialize from render if we have yet to initialize… I.e., rather than throw — take extra steps to initialize just in time in this case. Users can already call like element.connectedCallback() to achieve this by less-semantic means. The main issue here is that we are not connected… so we cannot really know if we have all the right attributes — but maybe that’s alright (they will eventually become consistent via attributeChangedCallback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions