Search code examples
polymerlit-element

Lit-element with Object-type properties


How to use Lit-element with Object-type property? I think defining myelement works:

static get properties() {
    return {
        whales:Object
    }
}
constructor() {
    super();
    this.whales={"nb":0};
}

html, this works also:

       <my-element id="mytest" whales='{"nb":2}'></my-element>

But I can't get setAttribute to work:

myElement.setAttribute("whales", {"nb":4});

EDIT: Thank you mishu, your answer helped me to solve my problem. Here is full working example, if someone wants to know. However there is still one thing I couldn't get working: I don't know how to give a property initial value declaratively, if the value is an object (object is handled as a string).

index.html:

    <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Lit-html test</title>
</head>
<body>
  <script type="module" src="./components/my-e.js"></script>

  <button id="reset" onclick="reset()">reset</button>
  <p>1 works: <my-e id="mytest"></my-e></p>
  <p>2 doesn't work: <my-e id="mytest2" person='{"name":"Joe", "age":32}'></my-e></p>
  <script src="main.js"></script>
</body>
</html>

main.js:

     function updatePerson(e) {
  var myE = e.target;
  myE.person = e.detail;
  myE._requestRender();
}
function reset() {
  var p = { "name": "Jack", "age": 20 };
  var myE = document.getElementById('mytest');
  myE.person = p;
  myE._requestRender();

  myE = document.getElementById('mytest2');
  myE.person = p;
  myE._requestRender();
}
document.getElementById('mytest').addEventListener('person', updatePerson);
document.getElementById('mytest2').addEventListener('person', updatePerson);

my-e.js:

import { LitElement, html } from './lit-element.js';
class MyE extends LitElement {
  static get properties() {
    return {
      person: Object
    }
  }
  constructor() {
    super();
    this.person = { "name": "Paul", "age": 40 };
    this.addEventListener('click', async (e) => {
      await this.renderComplete;
      var p = {};
      p.name = this.person.name + ", a";
      p.age = this.person.age + 1;
      this.dispatchEvent(new CustomEvent('person', { detail: p }))
    });
  }
  _render({ person }) {
    return html`
         <p> Name: ${person.name}</p>
         <p>Age: ${person.age}</p>
    `;
  }
}
customElements.define('my-e', MyE);

Solution

  • There you are trying to update a property, not really to set an attribute, and you don't have reflectToAttribute on the property. But you can try to use simply:

    myElement.whales = {nb: 4};
    

    UPDATE: I see that you changed the "scope" of the question.. so, you should be able to pass an object declaratively as long as the JSON is correct. You can see it in this demo.