DEV Community

Cover image for Not Another To-Do App: Part 10
Westbrook Johnson
Westbrook Johnson

Posted on

Not Another To-Do App: Part 10

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 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 so you too can know all of our characters’ backstories...

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

Reusable and Scaleable Data Management

Reusable and Scaleable Data Management

Photo by Francesco Ungaro on Unsplash

You know what’s kind of popular right now? Functional programming. You know what’s a great way to deliver features build to take advantage of functional programming concepts? ES Modules. You know what’s a great way to manage logic trees without relying on switch or if/else statements? The strategies pattern. What do you get when you mix them all together? Reusable and Scaleable Data Management. Or, at least I certainly hope so (yes, that’s another good one to take down to the comments)’s how I did it.


On the reusable end of the spectrum, let’s start with the functional interface by which we interact with the lifecycle of our list of to-dos (creating it, adding to-dos to it, and completing to-dos on it). Access to this can be gained via import { newToDos, addToDo, completeToDo } from './to-do-manager';. Here we get functional controls to initialize a new set of to-dos (i.e. return []), add a to-do (i.e. return [...todos, newTodo]), and remove a todo (i.e. return [...todos.filter(todo => !== completedId)]. Across each of these, we establish and maintain the identity of our individual to-dos while generating a new identity for the resulting list of to-dos, which will trigger the render pipeline in our LitElement based application. Further, their being exports allows them to be used and reused across our application and tests while being prepared for being made an external dependency if at some point this data became useful across multiple applications. If you want to use them in your To-Do application, fork me on GitHub!


On the scaleable side of the spectrum, we’ll be looking at the rest of the code in [src/to-do-manger.js]( which covers the ability to deliver work level customized suggestions for the user via the workLevelMessage(todos) export. While this data is also structured for use across the application and possible externalization as well, what’s really nice about it is how it is structured to scale.

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

export function workLevelMessage(todos) {
    return workLevelMessages[workLevelMeter(todos)];
Enter fullscreen mode Exit fullscreen mode

Notice how rather than attempting to structure an extended if/then tree or switch statement to outline which the message to return from [workLevelMessage]( the [workLevelMeter]( method relies on a series of object and array methods (thanks to our previous commit linting experience) to resolve the appropriate message. This means that regardless of whether to the current five levels of workloads and their associated messages, to a single one, or to fifty levels, this same logic will apply. We don’t need to go about adjusting what could easily become an awkward logic tree when you choose to make additions to the messages delivered or alterations to the levels at which their delivered, we just add the associated information to the data structure:

export const workLevelMessages = {
  0: 'Looks like you don\'t have anything to do right now. Take a break!',
  1: 'Looks like you\'re almost done. Keep it up!',
  2: 'Still a little more work to do. Don\'t loose focus!',
  3: 'It\'s a tough job, but somebody\'s got to do it.',
  4: 'This may look like a lot, but I know you can do it!',
  5: 'Maybe it\'s time to take a vacation? I won\'t judge.',
  /* New message */ 6: 'There\'s a new message in town!',

export const workLevelByTodoCount = {
  0: 0,
  3: 1,
  6: 2,
  9: 3,
  14: 4,
  /* New work level */ 50: 5,
Enter fullscreen mode Exit fullscreen mode

The above additions will immediately be available to uses with 50 or more to-dos, no logic alterations needed. And, even better, with the additional export of [workLevelMessages](workLevelMessages) and [workLevelByTodoCount]( those additions are also immediately added to the testing process.

And, in the end...

If you are sure I’m wrong, want to celebrate how right I am, or teach me ways I can be even crazier/insightful/progressive/right/et al. about anything you’ve read this far, I hope you know the refrain...the comments you take, and equal to the comments you make. Or at least I heard (something like) that somewhere.

As is noted above, the code shared throughout our conversation to date has not always been what ended up as final in my application. In case you’ve not gotten a chance to see what did, feel free to read the whole codebase on GitHub.

GitHub logo Westbrook / to-do-app

An open-wc powered To Do application

Open-wc Starter App

Built with open-wc recommendations


To get started:

git clone
cd open-wc-starter-app

npm install
npm start
Enter fullscreen mode Exit fullscreen mode

Live demo on Netlify.


  • start runs your app with auto reload for development, it only works on browsers which support modules for faster builds
  • start:es5 runs your app for development, it only works on browsers that don't support modules (IE11)
  • build builds your app for production and outputs it in the /dist folder
  • start:build runs your built app using a plain web server, to prove it works without magic 😃
  • build:stats creates an analysis report of your app bundle to be consumed by Webpack Visualizer and Analyser
  • test runs your test suite
  • lint runs the linter for your project

You can also see the current final application on Netlify. It’s tied to the GitHub repo above, so by current...I really mean it. It’s putting all of the ideas we’ve discussed in action live on the internet, and I hope the conversations we’ve shared about the development of it have proved useful to you in some way.

To bring us back to where we started, here’s a little refresher on the concepts that I wanted to find their way into my little To-Do app:

  • component-based code architecture
  • custom property based style API
  • event-based state management
  • style sharing
  • unit testing
  • web component-based UI

Over the course of some tightly related and others wildly tangential approaches, I hope you agree that I did a decent job of making a pass at each and every one of them. Some of these techniques are enabled by the team behind Open Web Components and their brand new Starter App. Some of them are rooted deeply in the tools recommended therein. And, others are flights of fancy that I’ve cooked up or heard over the course of years working with applications on the web.

If I haven’t said it yet, or in some cases if you hadn’t heard it yet, I’m not planting a stake in the ground to say that any of them are bar none the best in their class, and even less so am I trying to say that any of them would apply to projects of any size or holotype. What I do hope is that maybe like yet another set of interesting voices I follow in the field the subjects covered so far spark, not joy, but an interesting conversation between you and your other self, you and your team, you and me, or possibly even any small part of the larger javascript community. The more we get together to talk about our techniques and fret out the edge cases and the exactitudes that make them up, the happier we’ll be. (Oh, look, maybe I did mean for it to spark joy...) So, take the discussion to the comments below, the @ messages on Twitter, your favorite Slack, or this one were working with the web platform, web components, LitElement, and Open Web Components are all trending (at least most of the time), and I’ll see you there!


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 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:

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 an issue, submit a PR, or fork a repo to get in on the action!

Top comments (0)