Back to Lit

02

packages/lit-dev-content/site/tutorials/content/custom-attribute-converter/02.md

latest2.1 KB
Original Source

In the last step, you added a dateStr property that could be set from an attribute, but your component's date property is still being set with JavaScript. Requiring JavaScript to set a property is not ideal for users of a <date-display> because setting properties this way is not as readable or easy as setting attributes.

In this step, you'll add code to synchronize the date property with the dateStr property whenever dateStr changes.

Accept date-str as an attribute

  • Remove the <script> tag in index.html.
  • Pass 05/05/22 to the date-str attribute of date-display.

index.html

html
<body>
  <date-display date-str="05/05/22"></date-display>
</body>

Now you may notice that the date displayed is not the same as the one you passed in. This is because the date property is being rendered. date needs to be synchronized with dateStr whenever dateStr changes.

Update date when dateStr changes

  • On each change convert the dateStr value to a JavaScript Date object.
  • Update the date property to reflect the user-defined date so that it can be displayed.

{% aside "positive" %}

The willUpdate method is a good place to reconcile two different reactive properties.

For more information, see Lit lifecycle!

{% endaside %}

date-display.<ts-js></ts-js>

{% switchable-sample %}

ts
export class DateDisplay extends LitElement {
  ...

  willUpdate(changed: PropertyValues<this>) {
    if (changed.has('dateStr') && this.dateStr) {
      this.date = new Date(this.dateStr);
    }
  }

  ...
js
export class DateDisplay extends LitElement {
  ...

  willUpdate(changed) {
    if (changed.has('dateStr') && this.dateStr) {
      this.date = new Date(this.dateStr);
    }
  }

  ...

{% endswitchable-sample %}

Now the correct date should be displayed when the date-str attribute changes!

Adding the dateStr property and imperative code in willUpdate() works, but it's not ideal. We don't recommend using this pattern in your own code. Instead, you should use a custom attribute converter, as shown the following steps.