Not Another To Do App

Getting your hands dirty and feet wet with Open Web Component Recommendations…sort of: Part 7

westbrook
5 min readFeb 27, 2019
May all your to do lists be short, if not empty! How better to give you time to think of the next great thing to do?

Welcome to “Not Another To Do App”, an overly lengthy review of making one of the smallest application every developer ends up writing at some point or other. If you’re here to read up on a specific technique to writing apps or have made your way from a previous installation, then likely your in the right place and should read on! If not, it’s possible you want to start from the beginning so you to can know all of our characters’ back stories

If you’ve made it this far, why quit now?

Does Your Component Really Need to Know That?

Photo by Mathew Schwartz on Unsplash

It’s hard to say whether it comes from my training in Agile, or my learnings about Lean, or my training in agile (big A, little a, if you know…you know), or my own musings on the MTU, but I’ve grown quite fond of not doing things that don’t have to be done. Along those lines, I often have overly long conversations with myself as to where I should position the control over a component; it’s content, it’s functionality, it’s styling, everything. I spent a good amount of time thinking about this particularly in relation to the implementation of my app’s to-do element.

Initially, in keeping with a least amount of work approach, I felt I could get away with comparing my to dos with string based equality. There was no data to define them beyond the text string of the to do, so I wanted to get away with code so simple as:

<to-do todo="I've got stuff to do"></to-do>

A simple string meant I could rely on attribute binding to push the necessary data into my to-do element, and I could call it a day. However, a quick self QA (quality assurance test) of this will show you the folly of this in a simple equality world:

<to-do todo="I've got stuff to do"></to-do>
<to-do todo="I've got stuff to do"></to-do>

When you’ve got two to dos of the same name, you also have two to dos of the same equality, which means that “completing” one will accidentally complete both. What’s a person with lots of to do with the same text to do?

First, I thought to do this:

<to-do todo='{"todo": "I've got stuff to do"}'></to-do>
<to-do todo='{"todo": "I've got stuff to do"}'></to-do>

Thanks to the LitElement base class that open-wc’s Starter App supplies to build my web components with, I could declare my todo property as {type: Object} and I’d get the serialization of that attribute string into an actual Object for free. That object would then have a unique identity between my individual to-do elements and I could rely on equality checking again to “complete” one to do and not the other, and all was right with the world.

Wrong.

Relying on data that is being serialized across a component boundary internal to an application means that new identities are going to be created at times that are likely not the ones you meant. Particularly, when serializing into and out of a string via the binding outlined above, the external and internal identity of your objects will not be shared, which is how I had made my way to the following code:

<to-do .todo="${todo}"></to-do>

Using property binding means that we can skip the requirement for string serialization and that not only will each to-do element have a todo with a unique identity, regardless of the work needed to display them, that identity will be maintained across component boundaries. Rich data communication in a web component? You don’t say…

With that decided, I spent a little time with the style application I hoped to achieve. I decided to invert the standard styling approach and rather than rely on to-do element internals (with the likely help of CSS custom properties) to style the to do text, I chose to apply it through the light DOM so that the parent element would have control of the styling. It’s a small difference, but it’s one less thing that my custom element has to think about.

<to-do todo="${todo}">${todo.todo}</to-do>

What did I tell you, a small change! And, internally this change is paired with the addition of a slot element to display the content projected into your Shadow DOM from outside. In this case, that looks like:

render() {
return html`
<div>
<slot></slot> <!-- <E<=<- Look, I'm a slot! -->
</div>
<button
@click="${this.completeToDo}"
title="Complete To Do"
>
${iconMinus}
</button>
`;
}

Sometime your components need to know more than you initially hope that they will need to, whether for maintaining their fidelity internally, or for doing the same across component boundaries when constructing an application. Other times, you might be able to take some responsibilities off of the shoulders of your components. Getting philosophical and answering the question “Does Your Component Really Need to Know That?” can be an important step in both delivering the features you’re putting together now, as well as reducing maintenance requirements for later.

The Short Game

As voted on by a plurality of people with opinions on such topics that are both forced to see my tweets in their Twitter feed and had a free minute this last week, a 9000+ word article is a no, no.

So, it is with the deepest reverence to you my dear reader that I’ve broken the upcoming conversations into a measly ten sections. Congratulations, you’re nearing the end of the seventh! If you’ve made it this far, bless you. If you skipped to the middle, shame on you. If you’ve found even a little of this helpful, read another!

Special thanks to the team at Open Web Components for the great set of tools and recommendations that they’ve been putting together to support the ever growing community of engineers and companies bringing high quality web components into the industry. Visit them on GitHub and create and issue, submit a PR, or fork a repo to get in on the action!

--

--