Not Another To-Do App: Part 4
Tags: openwc, linting, webcomponents, javascript
Published: 2019-08-25 14:04:32

#### Getting your hands dirty and feet wet with Open Web Component Recommendations...sort of.

> _This a cross-post of a Feb 26, 2019 article from [Medium](https://medium.com/@westbrook/not-another-to-do-app-169c14bb7ef9) that takes advantage of my recent decision to use Grammarly in my writing (so, small edits have been made here and there), thanks for looking again if you saw it there 🙇🏽‍♂️ and if this is your first time reading, welcome!_

_Welcome to “Not Another To-Do App”, an overly lengthy review of making one of the smallest applications every developer ends up writing at some point or another. 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 you are in the right place and should read on! If not, it’s possible you want to [start from the beginning](https://dev.to/westbrook/not-another-to-do-app-2kj9) so you too can know [all of our characters’ backstories...](https://github.com/Westbrook/to-do-app)_

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

<hr/>

# Measure Twice, Lint Once

![Measure Twice, Lint Once](https://thepracticaldev.s3.amazonaws.com/i/2i1f74tq26nescs51siu.jpeg)
<figcaption>Photo by <a href="https://unsplash.com/@yer_a_wizard" target="_blank">Fleur Treurniet</a> on <a href="https://unsplash.com/" target="_blank">Unsplash</a></figcaption>

It may already too late to stop an exasperated comment or two from readers that have made it this far in response to a somewhat questionable block of code shared in a previous section. While accurately delivering the content to our application that is needed to pass the test of “it renders to do elements to the DOM for each of the to-do items in your list”, the following code sample sparks the ire of another feature that the open-wc team has provided our application:

```js
render() {
    return html`
        ${this.todos.map(todo => html`
            <to-do>${todo}</to-do>
        `)}
    `;
}
```

## _Linting!_

![`.map` is disallowed in templates...](https://thepracticaldev.s3.amazonaws.com/i/jtffdb04o4mpvmwxjku1.png)
<figcaption>`.map` is disallowed in templates...</figcaption>

As you can see in the terminal readout above, the inclusion by open-wc’s generator of [`eslint-plugin-lit`](https://www.npmjs.com/package/eslint-plugin-lit) gets right into helping your write cleaner, more performant code with a number of rules built for `lit-html` based templating. Beyond not getting to rely on `.map` in your templates, you’ll also be told when you’re binding the same attribute multiple times to a single element (i.e. `<x-foo bar=${x} bar=${y} baz></x-foo>`), when you’re redundantly using template literals (i.e. `foo ${‘bar'}`), when you’re bindings are in invalid positions (i.e. `<x-foo></${expr}>`), and much more. Luckily, in the case of my `.map` the steps to correct the error are few, they make our template much more readable, and they prepare the code for reusability as we’ll get into later.

```js
import { renderTodos } from './to-do-ui';

// ...

render() {
    return html`
        ${renderTodos(this.todos)}
    `;
}
```

However, this is not the only part of the lint report that surprised me. The following caught me as well:

![No `for(let y in x)`?](https://thepracticaldev.s3.amazonaws.com/i/yl641c8at9cbo3vrswb1.png)
<figcaption>No `for(let y in x)`?</figcaption>

I actually tripped this alert in two related places (one on the application side, one of the testing side of the same feature) so the logic to correct one mostly applied to the other. In the case of one instance, the code was as follows:

```js
for (const todoCount in workLevelByTodoCount) {
    if (todos.length <= todoCount) {
        return workLevelByTodoCount[todoCount];
    }
}
return Object.keys(workLevelByTodoCount).length;
```

Which when delivered via object/array methods get you the same functionality with a little bit more clarity while you’re at it:

```js
const workLevelCounts = Object.keys(workLevelByTodoCount);
const count = workLevelCounts
    .find(todoCount => todos.length <= todoCount);
return typeof count !== 'undefined'
    ? workLevelByTodoCount[count]
    : workLevelCounts.length;
```

Beyond the above results, I was also hit a number of other smaller linting errors and warnings that I’m glad to have out of my code base with the first call to `git commit -am 'Code with some linting errors'`. It’s nice to know someone’s got your back when it comes to these little nit-picks that can have compounding negative effects on your code over time.

## What’s More

It’s also nice when the tools a project adds to help it’s users be better (like this linting on commit) does the extended work of helping to make the project itself better. Once I had finished working through my list of linting issues, I found that there was an extra one that I couldn’t explain.

![Even the generator needs to be linted, sometimes.](https://thepracticaldev.s3.amazonaws.com/i/dcl0x26124cqcnpwt55t.png)
<figcaption>Even the generator needs to be linted, sometimes.</figcaption>

Turns out that some things had slipped by in the development process of the generator. Shortly after catching this and submitting [an issue](https://github.com/open-wc/open-wc/issues/246) in the open-wc project, it was tidied right up.

<hr/>

# 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.

{% twitter 1098196160613896192 %}

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 first! If you’ve enjoyed yourself so far, or are one of those people that give a new sitcom a couple of episodes to hit its stride, here’s a list of the others for you to put on your Netflix queue:

- [Not Another To-Do App](https://dev.to/westbrook/not-another-to-do-app-2kj9)
- [Getting Started](https://dev.to/westbrook/not-another-to-do-app-3jem)
- [Test Early, Test Often](https://dev.to/westbrook/not-another-to-do-app-2m9a) (I could use some unit tests on these articles...)
- Measure Twice, Lint Once (you are here)
- [Make it a Component](https://dev.to/westbrook/not-another-to-do-app-part-5-5d7o)
- [Make it a Reusable Part](https://dev.to/westbrook/not-another-to-do-app-part-6-an)
- [Does Your Component Really Need to Know That?](https://dev.to/westbrook/not-another-to-do-app-part-7-3cm7)
- [Separate Things Early, Often, and Only as Needed](https://dev.to/westbrook/not-another-to-do-app-part-8-3lic)
- [Some Abstractions Aren’t (Just) For Your App](https://dev.to/westbrook/not-another-to-do-app-part-9-10j3)
- [Reusable and Scaleable Data Management/And, in the end...](https://dev.to/westbrook/not-another-to-do-app-part-10-mp6)
- [See the app in action](https://gifted-lamport-70b774.netlify.com/)

<hr/>

Special thanks to the team at [Open Web Components](https://open-wc.org/) 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](https://github.com/open-wc/open-wc) and create an issue, submit a PR, or fork a repo to get in on the action!