Víctor
Víctor

Reputation: 3039

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.

Upvotes: 0

Views: 710

Answers (2)

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;
  }
}

Upvotes: 1

Benny Powers
Benny Powers

Reputation: 5836

If you don't want to apply a getter, then updated is your best bet

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

class MyElement extends LitElement {
  static get properties() {
    return {
      one: {
        type: String,
        attribute: 'foo',
      },
      two: {
        attribute: false
      }
    };
  }

  updated(changed) {
    if (changed.has('one')
      this.oneChanged()
  }

  oneChanged() {
    this.two = calculateTwo(this.one);
  }
}

Upvotes: 0

Related Questions