lit / lit-element

LEGACY REPO. This repository is for maintenance of the legacy LitElement library. The LitElement base class is now part of the Lit library, which is developed in the lit monorepo.
https://lit-element.polymer-project.org
BSD 3-Clause "New" or "Revised" License
4.49k stars 319 forks source link

Component, reflected property type:Number and null/undefined #1174

Closed tamis-laan closed 3 years ago

tamis-laan commented 3 years ago

Given a component with a property of type Number:

@customElement('my-component')
class myComponent  extends LitElement {

  static get properties() {
    return {
      property:{type:Number, reflect:true}
    }
  }

  render() {
    return 'hello world'
  }
}

I can set the property to null or undefined i.e. component.property = null. However if I set the property through a html attribute <my-component property=${null} /> the property becomes NaN.

Why is this? Why are null and undefined converted to NaN? I can understand that passing a string like "test" would be converted to NaN but not null and undefined. These are useful values to have.

sorvell commented 3 years ago

This is because lit-html currently does not modify the value passed to an attribute before calling setAttribute. This means an explicit null or undefined is directly passed to setAttribute where the value is coerced to a string (e.g. to "null" and "undefined"). These strings then become NaN when converted to a number.

If you want to avoid this conversion, you can bind to the property instead of the attribute (note the . before the attribute in the example below that indicates the binding is to a property not an attribute):

<my-component .property=${null}>

Note, the attribute value behavior for null and undefined is being changed in the next major version of lit-html slated to be released soon. In the new version explicit null and undefined will be set to attributes as empty string values which will be coerced to 0 in this case.

Hope that helps. If more explanation is necessary please feel free to re-open issue.