Creating a temperature converter with Custom Elements

Custom Elements are a part of Web Components, and they help you wrap up functionality inside a custom HTML element — any name you can think of, say <banana-stand> or <hipster-blog-article>.

If you’d like a deep dive on Custom Elements, see my earlier article, or the myriad of resources on Google. But instead of a longer explanation…

Let’s learn by doing!

…and build an element that converts between temperature units. This will swap units that a user may not understand, with units that they will.

the secret plan to convert from C to F

In practice, this means we’ll convert between freedom 🇺🇲 units, Fahrenheit— and those used literally everywhere else, Celsius.

Finally, before we start, I’m going to assume you’re using the latest Chrome or Safari. If you’re on Firefox or IE/Edge, you can include the latest polyfill.

1. The first thing you need is a name

Let’s choose an element name. The only requirement is that it has a  in it. I’m going to call my element x-temperature.

Let’s start by writing the boilerplate inside a HTML file —

<script>
class TemperatureElement extends HTMLElement {}
customElements.define('x-temperature', TemperatureElement);
</script>
<!-- sample use -->
<x-temperature>10&deg;C</x-temperature>

You should see — literally just “10°C”. That’s because our element does nothing. But we have a place to start adding callbacks.

“It’s The API, Stupid”

How will developers use your element?

Red Robot approves

Let’s ask developers to set an attribute with either C or F, whatever they start with. If the unit isn’t correct — e.g., the user is in en-US but the unit is in Celsius — we’ll then replace the element’s whole content.

2. The lifecycle of your element

HTML elements are created, then added to a document. Later on, if you’re modifying the DOM, they might be removed from the document.

Let’s take action when a x-temperature element is added to a document. Add the connectedCallback method inside the class, which checks the user’s language and what attribute is available

class TemperatureElement extends HTMLElement {
connectedCallback() {
const usesF = (navigator.language.indexOf('-US') !== -1); //🇺🇲
if (usesF && this.hasAttribute('c')) {
// TODO: convert to F
} else if (!usesF && this.hasAttribute('f')) {
// TODO: convert to C
} else {
// do nothing! Hooray!
}
}
}

3. Some brief math

Then add code for the F and C conversions —

    if (usesF && this.hasAttribute('c')) {
const inF = +this.getAttribute('c') * 9 / 5 + 32;
this.innerHTML = `${inF.toFixed(0)}&deg;F`;
} else if (!usesF && this.hasAttribute('f')) {
const inC = (+this.getAttribute('f') - 32) * 5 / 9;
this.innerHTML = `${inC.toFixed(1)}&deg;C`;

4. Test it out

Now that we have an API and code to implement it, update the element on your page, and add another element — so we have both systems represented:

Today it was as cold as <x-temperature c="10">10°C</x-temperature>, but elsewhere it was as warm as <x-temperature f="80">80</x-temperature>.

You should see something like this (or °F, if your browser is set to en-US — mine is in fact, not!). Congratulations — go reward yourself with a donut. 🍩 There’s also a live demo available here! 🎉

Extension tasks

We’ve only just scratched the surface, yet you’ve learnt something already. How could we improve this temperature converter?

there are a few ways!

Instead of specifying the temperature in an attribute, maybe you could (1) parse the existing HTML. You could also (2) ‘reset’ the innerHTML when the element is removed, to be a good citizen — cleaning up after oneself.

You could also create other elements — or change this element to support time/date conversions, length conversions. And once you’re done, let us know by publishing your work on https://www.webcomponents.org/.

#UseThePlatform