grohjy
grohjy

Reputation: 2149

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

Upvotes: 3

Views: 9083

Answers (3)

aj_shela
aj_shela

Reputation: 377

This example is tested in Lit 2.3.1. It should also work with lit-element.

Note: While passing object type attribute through html outer quotes must be single quotes and inner quotes must be double quotes.( like this: article='{"title": "Hello"}' ).

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lit 2.3.1</title>
</head>
<body>
  <my-page article='{"title": "Hello", "text": "World", "lines": 120}'></my-page>
</body>
</html>

my-page.js

import {LitElement, html} from 'lit';

class MyPage extends LitElement {
  static properties = {
    article: {
      type: Object, 
      attribute: 'article'
    }
  };

  render() {
    return html`
      <div>
        <p>${this.article.title}</p>
        <p>${this.article.text}</p>
        <p>${this.article.lines}</p>
      </div>`;
  }
}

customElements.define('my-page', MyPage);

Upvotes: 0

Phani
Phani

Reputation: 1901

<my-e id="mytest2" person='{"name":"Joe", "age":32}'></my-e>

Should have been <my-e id="mytest2" person='${{"name":"Joe", "age":32}}'></my-e> If you are using lit-extended. But this notation is going to be removed and is currently deprecated.

Hence the better option would be to write it as: <my-e id="mytest2" .person={"name":"Joe", "age":32}></my-e>

You can find the details at this documentation

Upvotes: 1

mishu
mishu

Reputation: 5397

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.

Upvotes: 3

Related Questions