<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrew Steele</title>
    <description>The latest articles on DEV Community by Andrew Steele (@andrew565).</description>
    <link>https://dev.to/andrew565</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4309%2F243ad2bc-869f-4563-ae10-a74b6f9d2703.png</url>
      <title>DEV Community: Andrew Steele</title>
      <link>https://dev.to/andrew565</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andrew565"/>
    <language>en</language>
    <item>
      <title>An Introduction to Narrative Coding</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Tue, 11 Mar 2025 23:07:20 +0000</pubDate>
      <link>https://dev.to/andrew565/an-introduction-to-narrative-coding-4fed</link>
      <guid>https://dev.to/andrew565/an-introduction-to-narrative-coding-4fed</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What is Narrative Coding&lt;/li&gt;
&lt;li&gt;What are Web Components&lt;/li&gt;
&lt;li&gt;
The App Itself

&lt;ul&gt;
&lt;li&gt;Humble Beginnings&lt;/li&gt;
&lt;li&gt;Creating and Reading TODOs&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi! My name is Andrew Steele, and I’m a Staff Software Engineer. I’ve been programming for over 20 years now, mostly in front-end web development, and one of my favorite techniques for ensuring clean, readable, and maintainable code is what I like to call "Narrative Coding". It’s a strategy that helps me stay on task while clearly communicating to colleagues at any skill level exactly what my code is doing and why. In this article, I’ll show you how to use Narrative Coding techniques in your own code, while also showing off the power and flexibility of Web Components, as we work together to build a very simple To-Do app. Even though the example code here will be written using JavaScript/Typescript, the tips and techniques should be applicable to any programming language.&lt;/p&gt;

&lt;p&gt;I'm going to skip several steps here and there so as not to bore you with the details, but if you want to see the whole app in its finished state you can check out the repo &lt;a href="https://github.com/andrew565/stencil-todo-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Narrative Coding
&lt;/h2&gt;

&lt;p&gt;At its most basic level, Narrative Coding is simply commenting your code and using descriptive variable and function names. Easy enough, right? The problem that many developers run into is a mindset that if you write clean code that it should be readable and self-describing without anything “extra”. But we’ve all run into “clean code” that takes extra brain power to interpret what it’s doing, let alone why.&lt;/p&gt;

&lt;p&gt;If you’ve ever taken over a legacy project that’s been around for a while, then you know how hard it can be to get started. First you have to interpret the file structure, then you have to figure out what each file does, and then, if you’re lucky or fastidious enough, you might be able to discern “why” it does what it does.&lt;/p&gt;

&lt;p&gt;Take for example this relatively straightforward function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you’re experienced with JavaScript and particularly array methods, you can figure out what this function does, but you will have to read it and think about it. Consider this same function, with a better function name and more comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Function to find the sum of an array of numbers&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getArraySum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Add the current value to the accumulator&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Accumulator starts at 0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how with a couple small additions it becomes as easy as reading to see and understand what this function is and what it does! Once you know that “acc” is short for “accumulator”, and “val” is short for value, and that the function expects an array of numbers, it’s a cinch to figure out that we’re summing up the values of the array and returning that sum.&lt;/p&gt;

&lt;p&gt;This is a very basic example, but it illustrates the value of commenting your code like it was a story, and using descriptive variable names. But we can take this even further using type annotations, whether with Typescript (which is way beyond the scope of this article) or with JSDOC comments, which is my preference since it "just works" in JavaScript in most modern IDEs and text editors like Visual Studio Code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Function to find the sum of an array of numbers
 * @param {number[]} arr
 * @returns {number}
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getArraySum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Add the current value to the accumulator&lt;/span&gt;
    &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Accumulator starts at 0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these simple additions we've increased our understandability greatly, and we get type checking in our editor! No more guessing what &lt;code&gt;arr&lt;/code&gt; should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Web Components
&lt;/h2&gt;

&lt;p&gt;To be honest, I don’t want to spend half the article explaining Web Components. The framework I am going to use here is called StencilJS, and here’s where you can read up on &lt;a href="https://stenciljs.com/docs/introduction" rel="noopener noreferrer"&gt;StencilJS and Web Components&lt;/a&gt;. StencilJS makes use of TypeScript rather than pure JavaScript, but the example code here should still be pretty easy to follow even if you're not familiar with either language.&lt;/p&gt;

&lt;p&gt;Short version: Web Components are a web technology that enables encapsulated and reusable code. They’re sometimes also called Custom Elements, as they can be used similarly to standard HTML elements like &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The App Itself
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Humble Beginnings
&lt;/h3&gt;

&lt;p&gt;Because this article is more about Narrative Coding than it is application development more generally, I chose to make a very, very simple app. This app will do the very basic CRUD (Create Read Update Destroy) for a todo list. It will not be pretty, but it will work.&lt;/p&gt;

&lt;p&gt;The first thing I do when starting a new project is to create an outline of what I want to accomplish. Often I will do this in a separate TODO file, but if I’m working on improving existing code then I will often make my outline within the code itself. Here's the TODO list for this app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; [ ] Setup a Stencil app
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Create the HTML base
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Create Web Components
&lt;span class="p"&gt;  -&lt;/span&gt; [ ] todo-list-app
&lt;span class="p"&gt;  -&lt;/span&gt; [ ] todo-item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that this is a very simple and short list right now. I can always expand it as I go, adding more todos as I discover more things that need to be done along the way.&lt;/p&gt;

&lt;p&gt;Reminder that you can check out the repo &lt;a href="https://github.com/andrew565/stencil-todo-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First I'll setup the Stencil app and the HTML "base" where the app will live. Then I'll create at least two components: the &lt;code&gt;todo-list-app&lt;/code&gt; where the application state will live, and a reusable &lt;code&gt;todo-item&lt;/code&gt; component I can use to represent each todo. Once I've got the basics out of the way, I'll work on wiring things together.&lt;/p&gt;

&lt;p&gt;Setting up Stencil is fairly straightforward but does require a couple extra steps. After running &lt;code&gt;npm init stencil&lt;/code&gt; and selecting &lt;code&gt;component&lt;/code&gt;, I then had to also run &lt;code&gt;npm install @stencil/core@latest --save-exact&lt;/code&gt; to update Stencil from 4.7.0 to 4.27.0. After that, I had to clear out the "starter" content (a name formatting utility and an example "my-component" component).&lt;/p&gt;

&lt;p&gt;Then I used &lt;code&gt;npm run generate&lt;/code&gt; to create "skeleton" components for &lt;code&gt;todo-list-app&lt;/code&gt; and &lt;code&gt;todo-item&lt;/code&gt;. You have the option when you use this command to generate components to also generate CSS, .spec (functional tests), and .e2e (End-to-end tests) files. I may or may not use them all, but I went ahead and generated them all to start out.&lt;/p&gt;

&lt;p&gt;Next, I added &lt;code&gt;&amp;lt;h1&amp;gt;Todo List App&amp;lt;/h1&amp;gt;&lt;/code&gt; to the &lt;code&gt;todo-list-app&lt;/code&gt; component, added the &lt;code&gt;todo-list-app&lt;/code&gt; component to the &lt;code&gt;index.html&lt;/code&gt; file, and fired up the server to make sure everything was working correctly (&lt;code&gt;npm start&lt;/code&gt;). So far so good!&lt;/p&gt;

&lt;p&gt;We'll need a way of creating todos, so I'll add an input and a button. They won't do anything yet, but that's next!&lt;/p&gt;

&lt;p&gt;Now we can check off the first several things on the TODO list, and add some more TODOs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;TODOs
&lt;span class="p"&gt;
-&lt;/span&gt; [x] Setup a Stencil project
&lt;span class="p"&gt;-&lt;/span&gt; [x] Create the HTML base
&lt;span class="p"&gt;-&lt;/span&gt; [x] Create Web Components
&lt;span class="p"&gt;  -&lt;/span&gt; [x] todo-list-app
&lt;span class="p"&gt;  -&lt;/span&gt; [ ] todo-item
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Tie todo-list-app button to &lt;span class="sb"&gt;`createTodo`&lt;/span&gt; function (create)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Make todo-list-app display (read) todo-item components for each todo
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Make it possible to edit (update) a todo-item
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Make it possible to delete (destroy) a todo-item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that these new todos encompass all of the CRUD actions we want to support in our app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating and Reading TODOs
&lt;/h3&gt;

&lt;p&gt;We're going to need some way of keeping track of what TODOs exist, and so this is where traditionally we'd bring in some kind of state manager. We're not going to get that fancy here, and instead each todo-item will keep track of its 'state' by itself. If the todo-item exists, then the task isn't done yet. If the task is done, the todo-item disappears.&lt;/p&gt;

&lt;p&gt;Before we can create a todo, we need to create a todo-item, so let's do that. Here's what the first version of todo-item's code looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoItem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This is the text of the to-do&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Edit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Delete&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Done&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Host&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have a &lt;code&gt;@Prop&lt;/code&gt; provided by Stencil to define a property on the custom element, which looks like this: &lt;code&gt;&amp;lt;todo-item text="Test Item"&amp;gt;&amp;lt;/todo-item&amp;gt;&lt;/code&gt;. We then render that out to the screen using JSX like so: &lt;code&gt;{this.text}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to dynamically create a todo-item, we have to go to the todo-list-app component and wire up the input and button we created earlier. Here's how I'd code my outline for this next step inside that component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoListApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Creates a new todo-item given the value of #todo-input&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;handleNewTodo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the value of #todo-input&lt;/span&gt;

    &lt;span class="c1"&gt;// Check that the text isn't an empty string&lt;/span&gt;

    &lt;span class="c1"&gt;// If not empty, create a new todo-item and add it to the DOM&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset #todo-input&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember, first we create an outline of what we want to code, and then we write the code to fit the narrative outline. You can probably already guess what this function will look like based on just this outline!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TodoListApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Creates a new todo-item given the value of #todo-input&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;handleNewTodo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the value of #todo-input&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#todo-input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Check that the text isn't an empty string&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// If not empty, create a new todo-item&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newTodo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo-item&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Set the text prop on the new todo&lt;/span&gt;
      &lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Add the new todo to the list of todos&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todoList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#todo-list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;todoList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset #todo-input&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Todo&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo-input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/input&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new-todo-button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleNewTodo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Add&lt;/span&gt; &lt;span class="nx"&gt;Todo&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todo-list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Host&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I added a few more comments and reordered as needed. That's OK! Sometimes we discover an extra step or two as we go, and so we adapt our outline comments to fit the real world.&lt;/p&gt;

&lt;p&gt;Now, are all of these comments strictly necessary? No, at this point I could probably remove half of them and most people looking at this code would still be able to understand what's going on. But here's the beautiful part about adding all these extra comments: they're free. When the compiler or whatever bundling tool you use compresses your code, it strips out the comments! So they don't take up any extra bytes. And those extra-long and descriptive variable and function names? They get replaced with one or two letters, so you might as well make them long and easy to understand when you're working on them!&lt;/p&gt;

&lt;p&gt;This means we now get to check off two more items on our TODO list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;TODOs
&lt;span class="p"&gt;
-&lt;/span&gt; [x] Tie todo-list-app button to &lt;span class="sb"&gt;`createTodo`&lt;/span&gt; function (create)
&lt;span class="p"&gt;-&lt;/span&gt; [x] Make todo-list-app display (read) todo-item components for each todo
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Make it possible to edit (update) a todo-item
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Make it possible to delete (destroy) a todo-item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;I think by now you probably have a good sense of how this works, so I recommend just checking out the &lt;a href="https://github.com/Andrew565/stencil-todo-app" rel="noopener noreferrer"&gt;repo&lt;/a&gt; if you're curious how the rest of the code turned out. You might notice that I consolidated the "delete" and "done" buttons into a single "done" button, since they do the same thing.&lt;/p&gt;

&lt;p&gt;I hope that this guide has helped you to think about how to better tell stories with your code. It makes it easier to read and understand, and helps whoever comes after you to know what decisions you made with your code and why, which aids in maintainability.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me if you have any questions, comments, concerns, or suggestions!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webcomponents</category>
      <category>javascript</category>
    </item>
    <item>
      <title>hafcaf - The No-Framework SPA Solution for Everyone</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Fri, 03 May 2019 03:00:33 +0000</pubDate>
      <link>https://dev.to/andrew565/hafcaf-the-no-framework-spa-solution-for-everyone-ckj</link>
      <guid>https://dev.to/andrew565/hafcaf-the-no-framework-spa-solution-for-everyone-ckj</guid>
      <description>&lt;p&gt;Think about the last time you had to learn a new front end framework. It might have been React, or Vue, or maybe you’ve been scared to learn any of them because of how much ”stuff” you have to learn and do before you even start. Did you know React has 42 pages of “guides” to help developers know the “right” way to program with React? Vue and Angular both have 31. Then there’s the size; it’s common for the final size of your app’s code to be measured in megabytes, meaning your users can wait several seconds before anything displays on the screen.&lt;/p&gt;

&lt;p&gt;Don’t even get me started on the ecosystem of build tools.&lt;/p&gt;

&lt;p&gt;So there I was, fed up with having to carry in my head these huge frameworks with all their nuances, and I decided there had to be a better way. A way to return to a simpler time, when you didn’t have to have a manual handy to be able to do the simplest tasks. Failing to find what I was looking for, I made my own solution.&lt;/p&gt;

&lt;p&gt;hafcaf weighs in at less than 1KB when minified and gzipped. It features only two pages of docs: a tutorial, and the API specifications. It requires you to learn only three methods: init, addRoute, and updateRoute. There’s only one (optional) lifecycle hook: onRender. Best of all, if you don’t want or need any of the JavaScript pieces, you can ditch them and the CSS-based routing function will still work.&lt;/p&gt;

&lt;p&gt;hafcaf really does let you have as little JavaScript as you want while offering just enough to make website and web app development a lot less painful. You can check it out &lt;a href="https://github.com/andrew565/hafcaf" rel="noopener noreferrer"&gt;here on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  How the Magic Happens
&lt;/h1&gt;

&lt;p&gt;hafcaf was inspired by an &lt;a href="https://www.smashingmagazine.com/2015/12/reimagining-single-page-applications-progressive-enhancement" rel="noopener noreferrer"&gt;article by Heydon Pickering&lt;/a&gt;. Here’s the gist: instead of JavaScript-powered URL re-routing - which often requires server-side directives to redirect all URLs to your index.html file - hafcaf uses CSS-based routing using the :target pseudo-class. This pseudo-class automatically responds to anchor tags that point to internal IDs using the href="#link" syntax.&lt;/p&gt;

&lt;p&gt;Don't worry, it's much easier than it sounds. Here's an example. Given this incredibly stripped-down example webpage code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"section1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    I'm the content for section one.
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#section2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Section Two&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"section2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    I'm the content for section two.
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#section1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Section One&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    I'm the content for the Home page.
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#section1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Section One&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#section2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Section Two&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using hafcaf, if you point your browser to &lt;code&gt;yourdomain.com/#section2&lt;/code&gt;, then the content for section 2 would show instead of both sections' content. hafcaf does this by hiding all content that isn’t being targeted, effectively showing only one 'page’ of content at a time. By default, hafcaf shows the last block of content; in the example above, “home” would show by default.&lt;/p&gt;

&lt;p&gt;Up to this point, we haven't needed to use any JavaScript at all. If static page loading meets you where you're at and provides all you need, then, by all means, don't bother loading the JavaScript file! That's the whole point of this library: you can have as little JavaScript in your site/app as you want, without sacrificing the speed and UX goodness of a SPA.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Little JavaScript Goes a Long Way
&lt;/h1&gt;

&lt;p&gt;If you don't mind a little bit of JavaScript in your codebase and want some fancy features like dynamic and/or lazy page loading, hafcaf’s JavaScript module gives you what you need - and nothing else.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support for asynchronous/dynamic page loading&lt;/li&gt;
&lt;li&gt;Support for lazy-loading (only request and load content when the user requests to view it)&lt;/li&gt;
&lt;li&gt;Automatic population and activation of a navigation menu (e.g. setting a menu item with a .active class)&lt;/li&gt;
&lt;li&gt;Addition of onRender actions which fire if and when a page is loaded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few different ways to make use of the dynamic page loading functionality, but the key parts boil down to two API methods: addRoute and updateRoute. What these methods do is probably pretty self-explanatory: addRoute adds a route entry to hafcaf's collection of routes, and updateRoute modifies the content and/or settings.&lt;/p&gt;

&lt;p&gt;The process basically looks like this: create a ‘page object’ with the basic information about your page, register it with hafcaf using the addRoute function, then go and fetch your page’s content in whichever way you like (I recommend fetch), and then finally call updateRoute with the actual content of the page.&lt;/p&gt;

&lt;p&gt;It may seem like a lot of steps, but it’s easier than you might think. hafcaf was designed to handle ‘asynchronous’ content in a very graceful way, that will fit into any flow or framework with ease. Starting with the previous example, let’s add a new page called page 3.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- page3.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"page-three"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Page 3&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Even moar content.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that there’s no extra DOCTYPE, head, or body sections, only the content we want for this new page. This is because we’re going to inject it directly into the existing page, so it doesn’t need all the extra definitions of a normal HTML file.&lt;/p&gt;

&lt;p&gt;Next, in your site’s main JavaScript file (or even in the index.html, if you want), set up the hafcaf.addRoute() function with an optional linkLabel property specified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;exampleDynamicView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page-3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;linkLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Page 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;hafcaf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exampleDynamicView&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This linkLabel property tells hafcaf to add a new entry to the page's menu with the label we specified, "Page 3". This extra property is optional if you want to define your menu in a different way, or if you don't have a menu.&lt;/p&gt;

&lt;p&gt;Now that you have a placeholder for your page, go and get the actual content. I prefer using fetch(), so here’s how I’d do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://yourserver.it/pages/page3.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page-3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;hafcaf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we process the response as text, then we assign that text to the innerHTML property of the new page object. If we had already had this content - maybe by fetching it earlier - we could have passed this same page object to addRoute() instead of updateRoute(); they work very similarly.&lt;/p&gt;

&lt;h1&gt;
  
  
  What else?!?
&lt;/h1&gt;

&lt;p&gt;hafcaf has lots more features too, including an onRender() lifecycle hook you can use to set up things like event handlers (e.g. onClick) or subscriptions to streams or web sockets - complete with an exitFunctions collection you can add any disposer functions to. Through a couple of plugin-like additions, you can also get access to hafcaf Barista which helps automate the fetch-and-update pattern I showed you above, and hafcaf Tamper - a simple templating language. Coming soon, I plan to add hafcaf Roaster for handling query params (they basically get ignored right now), and the one I’m most excited about: hafcaf Refill - an implementation of the Observer pattern that will leverage hafcaf Tamper to give you automatically-updating views; just like those fancy frameworks, but with much less cost.&lt;/p&gt;

&lt;p&gt;My main goal with hafcaf is to give people a simpler option. hafcaf isn’t meant to replace complex frameworks when you have to make complex applications. You’re not going to be making a 2D side-scroller with it. But for the majority of websites and apps that focus on displaying content with little or no ‘interactive’ parts, hafcaf might just make things simpler and easier.&lt;/p&gt;

&lt;p&gt;Check it out &lt;a href="https://github.com/andrew565/hafcaf" rel="noopener noreferrer"&gt;here on Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Which Array Function When?</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Tue, 08 Aug 2017 14:06:57 +0000</pubDate>
      <link>https://dev.to/andrew565/which-array-function-when</link>
      <guid>https://dev.to/andrew565/which-array-function-when</guid>
      <description>&lt;p&gt;There's a lot of hullaballoo some days about "you should use reduce more" or "you don't need a filter, use a map", or "For? Why not forEach?"&lt;/p&gt;

&lt;p&gt;The truth is, Arrays and all of their iterator functions can be confusing for beginners, so I'm going to try and simplify things for everyone by framing the question from the end: what do you want to get back?&lt;/p&gt;

&lt;h2&gt;
  
  
  Short version
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Return one thing for each existing thing: &lt;code&gt;map()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Return only some of the existing things: &lt;code&gt;filter()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Return only one new thing: &lt;code&gt;reduce()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Don't return anything, but do something with each existing thing: &lt;code&gt;forEach()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll give you a quick rundown of each, followed by examples using the older, non-arrow-function syntax as well as the newer arrow-function syntax.&lt;/p&gt;

&lt;h1&gt;
  
  
  Return one new entry for every existing entry: &lt;code&gt;map()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;If you have an array of values, and you want to do something to each entry in that array and return a new array with the new values, then &lt;code&gt;map()&lt;/code&gt; is your friend. Here's a simple function that takes an array and doubles every entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; [2, 4, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the same thing using the newer syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; [2, 4, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that, with the newer arrow syntax, we don't have to use the function keyword, the return keyword, or curly brackets. That's because arrow functions give us an implicit return for 'simple' functions like this one. You can read more about arrow functions &lt;a href="http://wesbos.com/arrow-functions/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, from Wes Bos.&lt;/p&gt;

&lt;h1&gt;
  
  
  Return a new array with only some of the existing entries: &lt;code&gt;filter()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Filter is probably the easiest array function to understand, because it is so well-named. Filter takes an array of values, performs a function or comparison on each value, and then returns a new array of just the values that pass it's test (what we call 'truthy' values).&lt;/p&gt;

&lt;p&gt;Here's an example that takes an array of numbers and returns just the ones that are larger than 5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; [9, 42]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the filter part with an arrow function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Return one new thing only: &lt;code&gt;reduce()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Sometimes you have an array of values and just want to return one new thing from them. Reduce takes an array, performs a function or comparison on each item, and then does something to what's called an 'accumulator'. This is one of those functions that's actually easier to describe with an example, because the terms one has to use to describe it are just as confusing as the function itself!&lt;/p&gt;

&lt;p&gt;Suppose you have an array of names, and you want to count the number of times the name 'Bob' shows up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charlie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charlie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberOfBobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numberOfBobs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again with arrows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberOfBobs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the arrow function didn't save us as much typing this time, because we had to provide two parameters to the function and then had logic before we could return, so we still needed curly brackets.&lt;/p&gt;

&lt;p&gt;The 0 at the end of the reduce function is the value we start off the accumulator with, adding 1 to it if the value we encounter is "Bob", otherwise we return the accumulator as it currently is. If you don't return anything, then the next time the function is run the accumulator will be &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do something with each array value but don't return anything: &lt;code&gt;forEach()&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Sometimes you'll have an array of values that you want to do something with, but don't need to keep track of what the return is from each function call. This is what &lt;code&gt;forEach()&lt;/code&gt; is for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And again with arrows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;originalArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Final Notes
&lt;/h1&gt;

&lt;p&gt;Simple and sweet. These are the simplest use cases I could come up with for each function to try and make it as easy as possible to understand when you should use each. There is a huge amount of tasks you can do with these functions, and there is an 'advanced' form of each of these functions that gives you the current index too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need it, use it!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>arrays</category>
    </item>
    <item>
      <title>My Favorite Git Helpers</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Thu, 08 Jun 2017 15:47:31 +0000</pubDate>
      <link>https://dev.to/andrew565/my-favorite-git-helpers</link>
      <guid>https://dev.to/andrew565/my-favorite-git-helpers</guid>
      <description>&lt;p&gt;You can find all of these aliases and functions (and then some!) on my Github here:Â &lt;a href="https://github.com/Andrew565/dotfiles" rel="noopener noreferrer"&gt;https://github.com/Andrew565/dotfiles&lt;/a&gt;. Read on for detailed explanations of what they are and what they do, and be sure to also check out my &lt;a href="https://andrewscripts.wordpress.com/2017/06/08/my-one-way-git-workflow-or-how-to-git-well/" rel="noopener noreferrer"&gt;preferred git workflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I use bash in my terminal. I know ZSH and fish and all the rest have their niceties, but I started with bash, and I like it fine enough, so that's what I use. &lt;/p&gt;

&lt;p&gt;My favorite thing to do in bash? Create aliases and helper functions for everything, especially Git commands. So, here's a list of some of my favs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bash Aliases
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Git Aliases&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;g&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git status"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git log"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;grh&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git reset --hard"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gcmm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git checkout --"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gsm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git stash &amp;amp;&amp;amp; git co master &amp;amp;&amp;amp; git stash pop"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gsd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git stash &amp;amp;&amp;amp; git co development"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gmd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git merge development"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gmm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git merge master"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gupdate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git co development &amp;amp;&amp;amp; git pull"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;glatest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git co development &amp;amp;&amp;amp; git pull"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gmupdate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git co master &amp;amp;&amp;amp; git pull"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gcm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"gmupdate"&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gphm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"git push heroku master"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of these are probably self-explanatory. Here are a couple commands that may not be immediately obvious:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias gsm="git stash &amp;amp;&amp;amp; git co master &amp;amp;&amp;amp; git stash pop"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is invaluable when I do work inÂ a feature branch that I actually wanted in the master branch. This doesn't happen as much anymore since most of the time I never commit directly to master, but it happens.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias gcmm="git checkout --"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command is when you have a fileÂ staged for commit and you don't actually want it to be part of the current commit. It could also be aliased as 'unstage'.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bash Functions
&lt;/h1&gt;

&lt;p&gt;Aliases will only get you so far. Sometimes you want to be able to bundle function calls together, or use variables. That's where bash functions come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  gnew - Create aÂ new branch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# create new branch from a default named branch&lt;/span&gt;
&lt;span class="c"&gt;# modify the first line to make it an argument if desired&lt;/span&gt;
gnew&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="nv"&gt;DEST_BRANCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
 : &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DEST_BRANCH&lt;/span&gt;:&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'master'&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
 git co &lt;span class="nv"&gt;$DEST_BRANCH&lt;/span&gt;
 git pull
 git co &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
 &lt;span class="c"&gt;# bundle install # If using Bundler (ruby)&lt;/span&gt;
 &lt;span class="c"&gt;# bundle exec rake db:migrate&lt;/span&gt;
 git push &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As it says, this creates a new branch based off of another branch. If you don't specify which branch to branch off of, it assumes/defaults to the 'master' branch. Use like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gnew new-branch-name old-branch-name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It then checks out the old branch/master, pulls to make sure you're branching off of the latest revision, then creates a new branch using the name you provided as the first argument. Commented out are commands to run bundler and rake db:migrate, only useful if you're working on a Ruby/Rails project. Finally, it does &lt;code&gt;git push -u&lt;/code&gt;, which pushes up the new branch and sets up the local branch to track the remote version, which makes future push and pull commands more seamless.&lt;/p&gt;

&lt;h2&gt;
  
  
  grmÂ - Git Rebase Master
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get the latest changes on master pulled down locally&lt;/span&gt;
&lt;span class="c"&gt;# and then rebase them into/onto the current branch&lt;/span&gt;
grm&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;CURRENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--abbrev-ref&lt;/span&gt; HEAD&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="c"&gt;# figures out the current branch&lt;/span&gt;
  git checkout master
  git pull
  git checkout &lt;span class="nv"&gt;$CURRENT&lt;/span&gt;
  git rebase master
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;a href="https://andrewscripts.wordpress.com/2017/06/08/my-one-way-git-workflow-or-how-to-git-well" rel="noopener noreferrer"&gt;my preferred workflow&lt;/a&gt; I always rebase the latest commits from master into my feature branch before I commit it. This keeps merge conflicts to a minimum and helps to keep the commit history clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  gsrm - Git Stash &amp;amp;&amp;amp; Rebase Master
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stash current, then update to latest, then pop the stash&lt;/span&gt;
gsrm&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  git stash
  grm
  git stash pop
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to grmÂ (and it even makes use of grm), this stashes whatever you're currently working that hasn't been staged/committed yet, then does the rebase, and then pops it out again. SUPER USEFUL if you know of upstream changes that you want to bring into your feature branch but what you're working on isn't ready to be committed. Side Note: don't use this as an excuse NOT to commit often. You should definitely still do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  gswitch - Quickly checkout branches
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gswitch&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;git branch | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
  git checkout &lt;span class="nv"&gt;$BRANCH&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch branches by issue number or feature keyword. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gswitch 1808 == git checkout features/1808-click-on-avatar&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;NOTE: only works well if you use a unique description, thus the recommendation to use issue numbers. Also works best if you delete your already-merged local branches regularly.&lt;/p&gt;

&lt;h1&gt;
  
  
  .gitconfig
&lt;/h1&gt;

&lt;p&gt;If you're not taking advantage of a global &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration" rel="noopener noreferrer"&gt;.gitconfig&lt;/a&gt;Â file, you're doing Git wrong. Here too I have a bunch of aliases, and a couple functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  aliases - Lookup what aliases you have
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;aliases = !git config --get-regexp 'alias.*' | colrm 1 6 | sed 's/[ ]/ = /'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;so&lt;/em&gt; need to recreate this in bash, I have a hard time remembering all of the aliases I've created (there &lt;em&gt;are&lt;/em&gt; a lot of them). ðŸ˜&lt;/p&gt;

&lt;h2&gt;
  
  
  cam - Commit while Adding files and attach a Message
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;cam = commit -am&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is (essentially) the same as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add . &amp;amp;&amp;amp; git commit -m "your message"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Be careful that you don't use this if you have any unstaged files you don't want to be committed, as it will add everything to the commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  last - What is the last thing I committed?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;last = cat-file commit HEAD&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  co - Checkout
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;co = checkout&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  delete-local - Clear out old branches quicker
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;delete-local = branch -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Somehow it's easier for me to remember &lt;code&gt;git delete-local&lt;/code&gt;Â than &lt;code&gt;git branch -d&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  delete-remote - Clear out remote branches quicker
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;delete-remote = "!sh -c 'git push origin :$1' -"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;CAUTION: This doesn't ask if you know what you're doing before you do it, so be careful!&lt;/p&gt;

&lt;h2&gt;
  
  
  branches - Get a list of all of your local branches
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;branches = "!sh -c 'git branch -a | grep -v remotes'"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can get rid of the &lt;code&gt;grep -v remotes&lt;/code&gt;Â if you want a list of remote branches too. This is another alias for 'natural language' purposes, just feels better to type &lt;code&gt;git branches&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  edit-unmerged &amp;amp; add-unmerged - Fix merge conflicts like a boss
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# use like `git edit-unmerged; ...edit..., ...test...&lt;/span&gt;
&lt;span class="c"&gt;# git add-unmerged; get commit || rebase --continue&lt;/span&gt;
edit-unmerged &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; code &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;f&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
add-unmerged &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; git add &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;f&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This saves me so much time it's ridiculous. Basically, &lt;code&gt;edit-unmerged&lt;/code&gt; looks at all of your files that are marked as "unmerged", meaning they have conflicts that need to be resolved. Then it opens them up in your code editor (replace &lt;code&gt;code&lt;/code&gt;Â above with the cli alias for your preferred editor, &lt;code&gt;vi&lt;/code&gt;, &lt;code&gt;emacs&lt;/code&gt;, &lt;code&gt;subl&lt;/code&gt;, etc.). When you're done, &lt;code&gt;add-unmerged&lt;/code&gt;Â finds that list of unmerged files again and does &lt;code&gt;git add&lt;/code&gt;Â on them (and only them, so you don't have to worry what else might get added). At this point, everything should be staged, so you can run &lt;code&gt;git commit&lt;/code&gt;Â or &lt;code&gt;git rebase --continue&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Notes
&lt;/h1&gt;

&lt;p&gt;Remember that a good craftsman never blames his tools. These helpers are not intended to be substitutes for actually knowing what you're doing. ðŸ˜‰ Here again is a link to my Github repo with these files:Â &lt;a href="https://github.com/Andrew565/dotfiles" rel="noopener noreferrer"&gt;https://github.com/Andrew565/dotfiles&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>cli</category>
    </item>
    <item>
      <title>How to Git Well</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Thu, 08 Jun 2017 15:27:16 +0000</pubDate>
      <link>https://dev.to/andrew565/how-to-git-well</link>
      <guid>https://dev.to/andrew565/how-to-git-well</guid>
      <description>&lt;p&gt;Throw a rock in any general direction, and you will hit yet another Git workflow. This one is mine, based on working with Git for 10+ years now. It makes use of &lt;code&gt;git rebase&lt;/code&gt;, so turn away now if you're scared of rebasing (and then go &lt;a href="https://www.atlassian.com/git/tutorials/merging-vs-rebasing" rel="noopener noreferrer"&gt;read this&lt;/a&gt; and realize that it's nothing more than another tool). BONUS: be sure to check out &lt;a href="https://andrewscripts.wordpress.com/2017/06/08/my-favorite-git-aliases-functions-and-configs/" rel="noopener noreferrer"&gt;my handy git helpers&lt;/a&gt; too!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Find your &lt;code&gt;origin&lt;/code&gt; repo&lt;/li&gt;
&lt;li&gt; Fork the origin repo to create your own repo

&lt;ul&gt;
&lt;li&gt;  If using Bitbucket, it will automatically set up your repo to sync with &lt;code&gt;origin&lt;/code&gt; unless you uncheck 'keep in sync'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Clone your fork to your local machine, where &lt;code&gt;origin&lt;/code&gt; will refer to your fork.&lt;/li&gt;
&lt;li&gt; Create a feature branch off of your local master

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;git checkout –b feature-branch-name&lt;/code&gt; replacing "feature-branch-name" with whatever name you want to give your branch&lt;/li&gt;
&lt;li&gt;  Good practice: make your branch names unique and specific to the task or feature you're working on. &lt;code&gt;branch-1&lt;/code&gt; is not a useful branch name, &lt;code&gt;time-travel-feature&lt;/code&gt; is better, &lt;code&gt;adding-unlimited-undo-in-cms&lt;/code&gt; is best.&lt;/li&gt;
&lt;li&gt;  Optional: push the new, empty feature branch to your fork’s remote endpoint using &lt;code&gt;git push –u origin feature-branch-name&lt;/code&gt;. This sets up 'tracking' so that every time you push going forward you don’t have to specify where, you do a &lt;code&gt;git push&lt;/code&gt; and it will already know where to push to. Same with &lt;code&gt;git pull&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; DO YOUR WORK

&lt;ul&gt;
&lt;li&gt;  Commit early and often. I recommend committing every time you get something to 'done' or at least working, but make a WIP (work in progress) commit anytime you need to switch tasks or want a waypoint for what you’re working on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Make a 'final' commit, if you haven’t already.&lt;/li&gt;
&lt;li&gt; Rebase your feature onto the current version of master (this reduces merge conflicts)

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;git rebase origin/master&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;code&gt;git rebase -i origin/master&lt;/code&gt; if you want to get fancy and pick and choose commits interactively&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Fix any merge conflicts, if any.

&lt;ul&gt;
&lt;li&gt; FIX, FIX some more, FIX again&lt;/li&gt;
&lt;li&gt; &lt;code&gt;git add .&lt;/code&gt; or &lt;code&gt;git add /file(s)/that/were/changed&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;code&gt;git rebase -–continue&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Having resolved any conflicts, push up your feature branch again, forcing your remote to overwrite whatever is already there (because rebasing will change the branch’s history and thus change its SHA checksum).

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;git push –f&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Create a pull request from your feature branch back up to the original &lt;code&gt;origin&lt;/code&gt; repo's master branch.

&lt;ul&gt;
&lt;li&gt; i.e. &lt;code&gt;fork/feature-branch-name -&amp;gt; origin/master&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Rest, reflect on what you have accomplished, and then start over again from step 4.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is what the cycle looks like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OriginMaster -&amp;gt; ForkMaster -&amp;gt; LocalMaster -&amp;gt; LocalFeatureBranch -&amp;gt; ForkFeatureBranch -&amp;gt; OriginMaster&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bitbucket will auto-sync OriginMaster and your ForkMaster if you're using Bitbucket. Then you have to pull down any updates from ForkMaster to your LocalMaster. Then, you switch to your LocalFeatureBranch and rebase it onto the latest changes in LocalMaster. Then you push up to ForkFeatureBranch, where you create a Pull Request from there to the OriginMaster, and the cycle starts over again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good practice&lt;/strong&gt;: any time you there is a merge of a significant amount into the 'origin' repo’s master branch, it’s a good idea to update your local master and rebase your feature branch. The more you keep your feature branch up-to-date with the latest changes, the easier merge conflicts will be to solve, and the fewer surprises you will have to deal with as you work.&lt;/p&gt;

&lt;p&gt;If you haven't checked it out yet, &lt;a href="https://andrewscripts.wordpress.com/2017/06/08/my-favorite-git-aliases-functions-and-configs/" rel="noopener noreferrer"&gt;go here&lt;/a&gt; for my handy git helpers that make this workflow super easy, fast, and intuitive (from the command line).&lt;/p&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Making a Card Game in JS, pt. 2 - The Surprises</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Thu, 11 May 2017 20:02:20 +0000</pubDate>
      <link>https://dev.to/andrew565/making-a-card-game-in-js-pt-2---the-surprises</link>
      <guid>https://dev.to/andrew565/making-a-card-game-in-js-pt-2---the-surprises</guid>
      <description>&lt;p&gt;This is the second part of my series on creating a card game based on &lt;a href="https://matthewlowes.com/games/" rel="noopener noreferrer"&gt;Dungeon Solitaire&lt;/a&gt; by Matthew Lowes. You can find the first part of this series &lt;a href="https://andrewscripts.wordpress.com/2017/03/16/how-to-make-a-card-game-in-javascript-part-1/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;The Surprises&lt;/h2&gt;

&lt;p&gt;Since my first post in this series, I ran into a very strange occurrence of events which led to the setup I had been working with falling apart to the point that I could no longer use it. As such, this post is going to focus briefly on some of the backend infrastructure changes I've made along the way.&lt;/p&gt;

&lt;h2&gt;In the Beginning, there was a Glitch, and it was Good&lt;/h2&gt;

&lt;p&gt;From the very beginning, I had envisioned this game being a Single-Page Application (SPA). There's nothing about this game that will require being backed by a database, nor is there any calculation so complex it can't be handled by the front-end. Knowing these things, I decided to start this app in &lt;a href="https://glitch.com/about/" rel="noopener noreferrer"&gt;Glitch&lt;/a&gt;, an online IDE of sorts that allows you to code in the browser. While there are many things that make Glitch awesome, what I like best is the live-reloading combined with auto-save, so you instantly get an online, up-to-date app that you can test as soon as you write a line of code. (Remixing someone else's app so you don't have to do all of the boilerplate yourself is also really really nice.)&lt;/p&gt;

&lt;p&gt;This was a fine setup until I ran into two issues which have more to do with me than they do with Glitch itself. The first was intermittent saving issues due to a spotty internet connection. Word to the wise: never do anythingÂ critical online over public Wi-Fi (looking at you Panera). This was tolerable until the time I lost 20+ minutes worth of work to it.&lt;/p&gt;

&lt;p&gt;The second issue was ES6/ES2015 support. I wanted this app to be as cutting-edge as plain JS can get, soÂ I wanted to make use of all of the bells and whistles of ES2015. Glitch's built-in ES2015 support is limited to whatever Node supports, which meant that while most things worked, I couldn't make use of &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;export&lt;/code&gt; statements to make my classes modular (this was way back in the time before Node added module support). While there are workarounds to this, I decided if I was going to go to all that trouble I would probably be happier just running it all locally.&lt;/p&gt;

&lt;h2&gt;CodeKit is It - Until I Break It&lt;/h2&gt;

&lt;p&gt;My favorite tool for running local projects is &lt;a href="https://codekitapp.com/" rel="noopener noreferrer"&gt;CodeKit&lt;/a&gt;. It's one of the easiest-to-use tools for handling all of the finicky backend server stuff and preprocessors that are annoying to configure and set up. Think of it like a GUI version of Grunt or Gulp. Usually, it works great. But because I can't leave well enough alone, I tried to mess with one too many settings while trying to get the import/export keywords to work and ended up breaking something bad enough that I couldn't get it to work anymore. Again, I'm sure this is another PEBKAC error, but I decided again that if I'm going to go to all of the trouble to try and fix what I did, I might as well bite the bullet and start over entirely with a hand-coded task-runner setup.&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;A More Modern Setup&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Because I almost never start things from scratch well, I decided to look up tutorials on what others recommend. I found &lt;a href="https://css-tricks.com/modern-javascript-ancient-web-developers/" rel="noopener noreferrer"&gt;this article from Gina Trapani&lt;/a&gt;Â whichÂ echoed a lot of frustrations us web devs have over the moving-target which is JS development these days. That article led to &lt;a href="https://github.com/verekia/js-stack-from-scratch" rel="noopener noreferrer"&gt;this extensive guide&lt;/a&gt;Â fromÂ Jonathan Verrecchia (works at Yelp), which I followed as closely as I could.&lt;/p&gt;

&lt;p&gt;The one step that blew me away was enabling Airbnb's styleguide on my code via ESLint. I consider myself a pretty goodÂ developer, soÂ I was shocked by how much sloppiness I had in my code.&lt;/p&gt;

&lt;h2&gt;All's Well That Ends...&lt;/h2&gt;

&lt;p&gt;Okay, so now I'm back on track. NEXT time I'll get back to the actual code at hand!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>games</category>
    </item>
    <item>
      <title>How to Make a Card Game in JavaScript, part 1</title>
      <dc:creator>Andrew Steele</dc:creator>
      <pubDate>Fri, 17 Mar 2017 15:09:13 +0000</pubDate>
      <link>https://dev.to/andrew565/how-to-make-a-card-game-in-javascript-part-1</link>
      <guid>https://dev.to/andrew565/how-to-make-a-card-game-in-javascript-part-1</guid>
      <description>&lt;p&gt;I've been playing this solitaire card game for awhile now called &lt;a href="https://matthewlowes.com/games/" rel="noopener noreferrer"&gt;Dungeon Solitaire - Tomb of the Four Kings&lt;/a&gt; by Matthew Lowes. The game simulates deep-diving into a tomb searching for the treasures buried there along with four kings. What I've always loved about this patience-style game is that it has simple-to-learn rules, uses a standard deck of cards so it can be played anywhere, and yet brings a rich story element to what would otherwise be ‘just another solitaire game'.&lt;/p&gt;

&lt;h2&gt;
  
  
  THE SETUP
&lt;/h2&gt;

&lt;p&gt;I made the choice early on to create this game using plain, pure, vanilla JavaScript. I'm a front-end engineer by trade, so I figure making this game in plain JS would give me the broadest appeal to potential employers. I've used and liked Ember and React, and I've even tried Angular, but I have always felt MVC frameworks often are overkill for most applications.&lt;/p&gt;

&lt;p&gt;The first iteration of this game is going to be text-based, with few or no graphics. A proof-of-concept. One of the first things I did was create a helper for DOM manipulation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could have made an alias to &lt;code&gt;document.querySelectorAll()&lt;/code&gt;, but my general preference is to use IDs for JavaScript hooks, so if I know I'm going to have a unique ID for the majority of actions, then there's no reason not to use &lt;code&gt;getElementById&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first object type I created was a Card object since this is a card game. JavaScript prior to ES6/ES2015 didn't have a real ‘class' system, so my first instinct was to create a plain object, especially since the Card object was going to be a very simple one. Here's how it looked at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Card&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; of &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would have been fine, of course, but as I refactored some things as I went I reconfigured it into a class. Here's what it looks like now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; of &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;suit&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;graphic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="c1"&gt;// TODO&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, not very different, but the class syntax does make some of it a little bit simpler to read. Also, I dropped the semicolons at the end of every line; again, for readability.&lt;/p&gt;

&lt;p&gt;The second thing I added was a &lt;code&gt;listItem()&lt;/code&gt; method. This gives me a quick and easy way to display this card in the DOM, similar to the convenience property for &lt;code&gt;Card.name&lt;/code&gt;. The class syntax here is interpreted by the browser the same as adding the function via the prototype chain, but it's a little bit cleaner to read.&lt;/p&gt;

&lt;p&gt;That's it for this post. Next time, I'll start looking at the Game and Level objects, as well as give you a look into the HTML structure of the app.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>games</category>
    </item>
  </channel>
</rss>
