My attempt at rewriting TodoMVC in Vanilla JavaScript

Adekoyejo Akinhanmi
codeburst
Published in
3 min readDec 29, 2017

--

I took the Udacity JavaScript Design Patterns Course when I was only a beginner and I absolutely struggled to understand its content. Much as it was hard, I took the challenge pretty serious and I set to rewrite the vanilla JavaScript version of the TodoMVC project. This post highlights my experience.

Points to note

  • The final version is in ES6
  • There are some missing features of the original project e.g. routing and localStorage
  • I tried to think differently from how the project was originally written.
  • Also, I used bootstrap and some custom css instead of the original project assets.
  • The code for this post can be found here and the demo is here.

First Attempt

The code for the first attempt started way back in late 2016. I had some time on my hands and I decided to put what I had learnt into practive. Ben, the course instructor, presented the MVC pattern in an MVO (Model, View, Octopus) pattern using plain JavaScript Objects. Therefore, I wrote my application using plain JS Objects.

Implementing simple features like adding or removing from the list was not hard. However, combining a simple template implementation and app-wide communication proved to be hard. In fact, the feature I found the hardest to maintain was app-wide events management. I used a small Pub/Sub module published by David Walsh here. My MVC model followed the convention below.

Convention for my MVC
  • The model publishes any changes/events
  • The controller subscribes to the changes/events and in turn controls changes and events between the view and the model.
  • The view does all it needs to do via the controller.

Although, this convention seemed to make sense at the time, I just didn’t know how to get the view to truly communicate its changes and expose it’s APIs. As such, I couldn’t implement features like filtering and clear completed.

Eventually, I abandoned the code in January, 2017.

Second Attempt

After dabbling with and even abandoning JavaScript for some time, I finally decided to retry the project some time in November, 2017. It took me about two working days amid other tasks to complete the second attempt.

At the start, I decided I was going to burn down the old one and rewrite a fresh one. I also decided to use the new ES6 features I had learnt and cut out the implementation of routing (i.e. locationHash change).

The Model and Collection

The Todo Model has only one method which was toggleCompleted. However, majority of the model management happened in the TodoCollection.

The first thing I did was read the source code for Backbone.js collections since I had used the library in the past. I tried to structure my TodoCollection APIs loosely based on Backbone. The main entry APIs were get and set.

The View

The view was loosely based on my understanding of how modern front-end frameworks work i.e. make changes to a virtual DOM and publish on next DOM render. I wanted an efficient way to handle this without implementing a virtual DOM so I found JavaScriptDocumentFragment. You can read about that here and here. There were perfect for my needs since I could do all the changes in memory before actually re-rendering the entire DOM.

The view exposed two render functions which were listRender and infoRender. These were largely dependent on the current view state which could be completed, all and active.

The Controller

The controller was able to perform the bulk of the work by calling an internal method updateView after every change whether in the Collection or in the View.

The updateView method is shown below:

Others

The main entry point into the app is index.js and I had some helper functions such as $parent to find the parent of a DOM node and htmlToDOM to convert an html String to a DOM node. The app was bundled with webpack and I used yarn as a package manager.

Conclusion

For me, this is a true indication of growth. I have learnt a lot and continue to learn more. If you enjoyed this post, please consider sharing and giving a few claps.

Cheers.

--

--