Search code examples
javascriptweb-componentlit-elementlit-html

How to map one attribute to two properties in litElement?


I am working in a litElement project, and in a component, I have an attribute that needs to be mapped to a property, and computed with a function to another one, something like this:


const calculateTwo(val) {
 return `${val} ${val}`
}

class MyElement extends LitElement {
  
  static get properties() {
    return {
      one: {
        type: String,
        attribute: 'foo',
      },
      two: {
        type: String,
        attribute: 'foo',
        reflect: false,
        converter: value => calculateTwo(value),
      },
    };
  }
}
<my-component foo="bar"></my-component>

If I do this, one is not setted with 'bar', but two is correct

If I remove the property two, one works properly.

What would be the better approach to achieve this?

I can go with the update function, but I would like to know if there is a better approach.

I don't want to use a getter function to one of the properties, because the function of the converter is pretty heavy and I don't want it to be called everytime that I want to access the prop.


Solution

  • I think that using property accessors could avoid calling to render twice.

    const calculateTwo(val) {
     return `${val} ${val}`
    }
    
    class MyElement extends LitElement {
      static get properties() {
        return {
          one: {
            type: String,
            attribute: 'foo',
          },
          two: {
            attribute: false
          }
        };
      }
    
      set one(value) {
        const oldValue = this._one;
    
        this.two = value;
        this._one = value;
    
        this.requestUpdate('one', oldValue);
      }
    
      get one() {
        return this._one;
      }
    
      set two(value) {
        const oldValue = this._two;
    
        this._two = calculateTwo(value);
    
        this.requestUpdate('two', oldValue);
      }
    
      get two() {
        return this._two;
      }
    }