<?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: Jacque Schrag</title>
    <description>The latest articles on DEV Community by Jacque Schrag (@jnschrag).</description>
    <link>https://dev.to/jnschrag</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%2F31429%2F401c789b-fc72-46c9-a16f-2f0a755d8823.jpg</url>
      <title>DEV Community: Jacque Schrag</title>
      <link>https://dev.to/jnschrag</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jnschrag"/>
    <language>en</language>
    <item>
      <title>Nevertheless, Jacque Coded, Even When She Wanted to Quit</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Sun, 07 Mar 2021 18:32:53 +0000</pubDate>
      <link>https://dev.to/jnschrag/nevertheless-jacque-coded-even-when-she-wanted-to-quit-3md5</link>
      <guid>https://dev.to/jnschrag/nevertheless-jacque-coded-even-when-she-wanted-to-quit-3md5</guid>
      <description>&lt;p&gt;Like many other people, my 2020 did not turn out the way I had thought it would. In January, I spoke at a conference and had more speaking &amp;amp; writing gigs lined up. I was anticipating a new role at work. I was excited, and ready to keep growing!&lt;/p&gt;

&lt;p&gt;By the time August hit, I was one breakdown away from quitting my job and permanently becoming a part of my couch.&lt;/p&gt;

&lt;p&gt;I was depressed, miserable, stressed, burnt out...and embarrassed that I felt that way. Even with the perfectly valid reason of &lt;em&gt;gestures at everything&lt;/em&gt;, I was ashamed of how I felt and frustrated by my inability to push through it so I could get back to doing the projects I enjoyed.&lt;/p&gt;

&lt;p&gt;I didn’t publish a single new blog post in 2020, nor did I work on a single side project. But I did start seeing a therapist, and being more open with friends &amp;amp; colleagues about how I was feeling. The support &amp;amp; encouragement I’ve received has been amazing, and for now, that’s more than enough for me.&lt;/p&gt;

&lt;p&gt;I still have days where I’d rather be a potato than a programmer. But I’m grateful for the creativity, joy, &amp;amp; delight that exist in this field, and want to continue to be a part of it even if I only have the energy to be a spectator.&lt;/p&gt;

&lt;p&gt;In 2021, I will continue to code, but not at the expense of my well-being. And if that means less talks, blog posts, and side projects, then that’s okay with me.&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
    <item>
      <title>Supported, Jacque Kept Coding</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Mon, 09 Mar 2020 03:29:49 +0000</pubDate>
      <link>https://dev.to/jnschrag/supported-jacque-kept-coding-1e32</link>
      <guid>https://dev.to/jnschrag/supported-jacque-kept-coding-1e32</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/jnschrag/supported-jacque-coded--486g"&gt;Last year&lt;/a&gt;, I shared how supported I've generally felt in the tech community since I started being a more active participant in it.&lt;/p&gt;

&lt;p&gt;I've continued to be supported this year in so many ways. I began writing about code online, and the reception by the Dev Community has been incredible. Writing those posts led to having more conversations and feeling more comfortable in sharing my own journey in becoming a better developer. Conversations online turned into speaking opportunities at meetups and conferences, with a few more to come.&lt;/p&gt;

&lt;p&gt;I'm grateful that I've had so many positive experiences this year, and have been actively encouraged and supported by so many people. I look up to so many of you, especially my fellow lady devs, and promise to continue to support you as you've supported me while I keep coding, writing, and speaking. I could not have done it without all of you. 💚&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
    <item>
      <title>Creating Pixel Art with CSS</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Wed, 12 Jun 2019 01:03:55 +0000</pubDate>
      <link>https://dev.to/jnschrag/creating-pixel-art-with-css-3451</link>
      <guid>https://dev.to/jnschrag/creating-pixel-art-with-css-3451</guid>
      <description>&lt;p&gt;I have always enjoyed looking at and creating pixel art. Before &lt;a href="http://pixelartmaker.com"&gt;online pixel makers&lt;/a&gt; were a thing, I used to spend hours making my own pixel art in Photoshop with the pencil tool. This article will show you how using CSS (and a tiny bit of HTML), you can use code to make your own pixel art creations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of &lt;code&gt;box-shadow&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;While it is 100% possible to create pixel art by creating a bunch of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s and changing their background color, that's a lot of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s to keep track of and copy if you want to reuse your pixel in multiple places. I prefer to create pixel art with a single &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, which we can do thanks to the &lt;code&gt;box-shadow&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;box-shadow&lt;/code&gt; is commonly used to create a drop shadow effect behind an element, like in the example below.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/OYKPrM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;How does that help us with creating the straight-edged pixel art? By removing the blur &amp;amp; spread parameters from the &lt;code&gt;box-shadow&lt;/code&gt; definition, we can straighten out the sides of the shadow.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/byXNOw?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Next, we want to move the shadow so it is beside the block instead of being behind it. We can do this by adjusting the X- &amp;amp; Y-offset parameters according to the rules below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;X-offset:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Positive value moves &lt;strong&gt;right&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Negative value moves &lt;strong&gt;left&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Y-offset:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Positive value moves &lt;strong&gt;down&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Negative value moves &lt;strong&gt;up&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Shadows inherit their dimensions from the element they're applied to. To move the shadow to the right of the block, we need to set the X-offset to be the same as the width of the block: &lt;code&gt;20px&lt;/code&gt;. If we change the Y-offset to &lt;code&gt;0&lt;/code&gt;, the result looks like if we had two blocks sitting side-by-side.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/byXNzw?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;It's starting to look like pixel art! But this only gives us two "pixels", and we're going to need a lot more than that. Thankfully, the &lt;code&gt;box-shadow&lt;/code&gt; property isn't limited to just one effect. By separating our effects with a comma, we can create multiple pixel-looking shadows.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/wbVaNy?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Now that we know how we can use &lt;code&gt;box-shadow&lt;/code&gt;, it's time to start making a real piece of pixel art.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Pixel Cat
&lt;/h2&gt;

&lt;p&gt;We're going to be creating a pixel version of Pusheen. If you're new to making pixel art, I recommend searching for existing art so you have a reference for where your pixels should be placed. I'm going to be recreating this version of pixel Pusheen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftenh2g5zhyijcy9fsw7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftenh2g5zhyijcy9fsw7o.png" alt="Pusheen pixel art that we will be recreating." width="380" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is made up of 414 pixels (23 columns x 18 rows). To help me easily identify the individual pixels, I've used Photoshop to overlay a grid on the reference image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9cxhc3igji0xk1cgtpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9cxhc3igji0xk1cgtpv.png" alt="Pusheen pixel art with grid overlay to help us easily identify the pixels." width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although you could start drawing your pixel from anywhere, I'm going to start in the uppermost left corner so I don't have to worry about any negative offsets in my &lt;code&gt;box-shadow&lt;/code&gt; effects.&lt;/p&gt;

&lt;p&gt;I'm also going to use SASS instead of vanilla CSS to avoid writing 414 &lt;code&gt;box-shadow&lt;/code&gt; declarations by hand. By utilizing a custom SASS function and lists, we can automate calculating the offset positions and make our code more DRY.&lt;/p&gt;

&lt;p&gt;First, I’m going to make some modifications to our &lt;code&gt;#cat&lt;/code&gt; block. Instead of applying the &lt;code&gt;box-shadow&lt;/code&gt; to the block itself, I’m going to apply it to a pseudo element instead that is absolutely positioned relative to the block. Why? Because &lt;code&gt;box-shadow&lt;/code&gt; doesn’t take up space, meaning if I were to put another element next to my cat block, it would sit on top of my shadows. If we make the size of the cat block the final size of our pixel art, we can avoid this problem, but we need the pseudo element to separately define the width/height of our pixels (remember, the size of the shadow is inherited from the element the box-shadow is applied to). This is what those changes look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nn"&gt;#cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;23&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pixel size * # of columns&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pixel size * # of rows&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// box-shadow will be applied here&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;Next, let’s set up some variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The width/height of each of our "pixels".&lt;/span&gt;
&lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Colors&lt;/span&gt;
&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$gray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#cdc9cf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$dkgray&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#a09da1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$pink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ffa6ed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we’re going to create a list to track what color each pixel should be. Starting on the left, let’s create a list for the first row.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could create new variables for each of the subsequent rows (&lt;code&gt;$second&lt;/code&gt;, &lt;code&gt;$third&lt;/code&gt;, etc.), but a better approach is to create a nested list, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$cat&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="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,//&lt;/span&gt; &lt;span class="m"&gt;1st&lt;/span&gt; &lt;span class="nf"&gt;Row&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$gray&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$t&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$gray&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$black&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="m"&gt;2nd&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;
  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Additional&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The nested list approach has the benefit of providing us with all the information we need to generate our &lt;code&gt;box-shadow&lt;/code&gt; effect for each of the cell: the X/Y positions to calculate our offset and the color of the shadow. We'll access that information with a custom "pixelize" function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing a SASS Function to Draw a Pixel
&lt;/h3&gt;

&lt;p&gt;Our "pixelize" function is going to do the heavy-lifting of turning our list of colors into usable &lt;code&gt;box-shadow&lt;/code&gt; definitions. I've provided line-by-line explanations of what this function does below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;pixelize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;$numRows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;@for&lt;/span&gt; &lt;span class="nv"&gt;$rowIndex&lt;/span&gt; &lt;span class="ow"&gt;from&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;through&lt;/span&gt; &lt;span class="nv"&gt;$numRows&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$rowIndex&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$rowIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$numCols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;@for&lt;/span&gt; &lt;span class="nv"&gt;$cellIndex&lt;/span&gt; &lt;span class="ow"&gt;from&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;through&lt;/span&gt; &lt;span class="nv"&gt;$numCols&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cellIndex&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nv"&gt;$color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$cellIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nv"&gt;$sep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;', '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;@if&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nv"&gt;$y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$sep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$sep&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$color&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="nv"&gt;$result&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;ul&gt;
&lt;li&gt;Line 1: The function takes two arguments: the list of &lt;code&gt;$colors&lt;/code&gt; and the &lt;code&gt;$size&lt;/code&gt; that the pixels should be&lt;/li&gt;
&lt;li&gt;Line 2: Initializes our &lt;code&gt;$result&lt;/code&gt; variable as a string. This is the variable the function will modify and return.&lt;/li&gt;
&lt;li&gt;Line 3: Returns the number of rows in the list using the built-in &lt;code&gt;length&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;Line 5: Starts a loop that iterates X times, where X is the number of rows in our list. The &lt;code&gt;$rowIndex&lt;/code&gt; will increment by 1 on each loop.&lt;/li&gt;
&lt;li&gt;Line 6: Calculates the Y-offset of all cells in that row. SASS Lists are index-1 (not index-0), so we subtract 1 from the current index so the 1st row has a Y-offset of 0, 2nd has Y-offset of 1, etc.&lt;/li&gt;
&lt;li&gt;Lines 7 &amp;amp; 8: Returns the value of the current list item (the list of colors for the row) &amp;amp; calculates its length to determine the number of columns in the row&lt;/li&gt;
&lt;li&gt;Line 10: Starts a loop to iterate over each column in the row&lt;/li&gt;
&lt;li&gt;Line 11 &amp;amp; 12: Calculates the X-offset of that cell &amp;amp; returns the corresponding color&lt;/li&gt;
&lt;li&gt;Lines 14-17: Sets the separator for the &lt;code&gt;box-shadow&lt;/code&gt; effects, but removes it for the first cell to ensure a valid property value.&lt;/li&gt;
&lt;li&gt;Line 19: Updates the &lt;code&gt;$result&lt;/code&gt; value to its existing value plus the new cell:

&lt;ul&gt;
&lt;li&gt;Separator&lt;/li&gt;
&lt;li&gt;X position * &lt;code&gt;$size&lt;/code&gt; = X-offset&lt;/li&gt;
&lt;li&gt;Y position * &lt;code&gt;$size&lt;/code&gt; = Y-offset&lt;/li&gt;
&lt;li&gt;Color&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Line 23 &amp;amp; 24: &lt;code&gt;$result&lt;/code&gt; is a string, so we use the &lt;code&gt;unquote&lt;/code&gt; function to remove the containing quotes. Finally, return the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Final Result
&lt;/h2&gt;

&lt;p&gt;Put it all together, and here is our final Pusheen pixel!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/eaqpJO?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Pretty neat! With a little refactoring, the use of CSS Variables, &amp;amp; a smidge of JavaScript, we could even allow users to select their own colors for their cats.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/jschrag/embed/ydyVjb?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I hope this post has inspired you to make your own pixel art. Even if it hasn't, I hope you've learned how you can use the &lt;code&gt;box-shadow&lt;/code&gt; property to create some neat effects in your projects. If you're interested in seeing more pixel art, including examples of how to animate them, check out "&lt;a href="https://css-tricks.com/fun-times-css-pixel-art/"&gt;Fun Times with CSS Pixel Art&lt;/a&gt;" by Geoff Graham on CSS-Tricks.&lt;/p&gt;

</description>
      <category>css</category>
      <category>tutorial</category>
      <category>art</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What are your "must have" custom snippets for your editor/IDE?</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Wed, 24 Apr 2019 13:50:33 +0000</pubDate>
      <link>https://dev.to/jnschrag/what-are-your-must-have-custom-snippets-for-your-editor-ide-3769</link>
      <guid>https://dev.to/jnschrag/what-are-your-must-have-custom-snippets-for-your-editor-ide-3769</guid>
      <description>&lt;p&gt;A custom snippet is a template that allows you to easily enter repeated code patterns. This &lt;a href="https://snippet-generator.app/"&gt;Snippet Generator&lt;/a&gt; by Pawel Grzybek  makes it easy to create your own for VS Code, Sublime, &amp;amp; Atom.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Refactoring the Worst Code I’ve Ever Written</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Thu, 18 Apr 2019 12:00:03 +0000</pubDate>
      <link>https://dev.to/jnschrag/refactoring-the-worst-code-i-ve-ever-written-42c7</link>
      <guid>https://dev.to/jnschrag/refactoring-the-worst-code-i-ve-ever-written-42c7</guid>
      <description>&lt;p&gt;During the recent &lt;a href="https://twitter.com/search?q=%23DevDiscuss"&gt;#DevDiscuss&lt;/a&gt; chat on "Developer Confessions", I confessed that I didn't really know what I was doing when I started my first dev job 3 years ago. To demonstrate my inexperience, I shared an example of the kind of code I was writing at the time.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1113248130600927232-723" src="https://platform.twitter.com/embed/Tweet.html?id=1113248130600927232"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1113248130600927232-723');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1113248130600927232&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The response I received has been overwhelmingly positive. Most of us have written "bad"* code that we're not proud of, but it's a sign of growth when you can look back at that older code, recognize how it could be better, and maybe laugh at yourself for the choices you made. In the spirit of continuing to learn, I want to share some of the ways I might solve this problem today.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Although this bit of code is silly and could have been written much more efficiently, hard-coding accomplishes the task it needed to just fine.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Context &amp;amp; Goals
&lt;/h2&gt;

&lt;p&gt;Before refactoring any legacy code, it's critical to step-back and assess the context that the code was written in. There could be an important reason for the &lt;del&gt;madness&lt;/del&gt; choices a developer made that were influenced by context that you might not be aware of (or remember, if it's your code). In my case, I was simply inexperienced, so this code can be safely refactored.&lt;/p&gt;

&lt;p&gt;The code was written for two data visualizations: &lt;a href="https://chinapower.csis.org/china-foreign-direct-investment/#global-foreign-direct-investment-stocks"&gt;"Global Foreign Direct Investment Stocks"&lt;/a&gt; (in/out) and &lt;a href="https://chinapower.csis.org/china-foreign-direct-investment/#china-bilateral-investment-outflows"&gt;"China Bilateral Investment Outflows"&lt;/a&gt; (China). They have similar data &amp;amp; functionality, with the primary goal allowing the user to explore the datasets by filtering by type, year, or region. I'm going to focus on the global data, but the China dataset can be refactored in a similar way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmxvwxyutr523lppanvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmxvwxyutr523lppanvn.png" alt="An interactive bubble chart showing global direct investment." width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's assume that changing one of the filters will result in the below values being returned:&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;let&lt;/span&gt; &lt;span class="nx"&gt;currentType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// or 'out'&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2017&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentRegions&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="s1"&gt;Africa&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="s1"&gt;Americas&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="s1"&gt;Asia&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="s1"&gt;Europe&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="s1"&gt;Oceania&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; The region checkboxes don't currently work this way, hence the "All" and "Partial" in the snippet, but this is how it should have been done.&lt;/p&gt;

&lt;p&gt;Finally, here is a simplified example of the data itself after it's been loaded in from a CSV:&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;in&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Asia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;out&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Asia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&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="c1"&gt;// Total Items in Array: ~2,400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Option 1: Initializing Empty Objects
&lt;/h2&gt;

&lt;p&gt;Beyond being hard-coded, my original snippet completely violates the Don't Repeat Yourself (DRY) approach to writing code. There are absolutely instances where repeating yourself makes sense, but in this case when the same properties are being repeated over and over again, it's a smarter choice to create the objects dynamically. Doing so also reduces the amount of manual work required when a new year is added to the dataset, and limits the opportunities for input error.&lt;/p&gt;

&lt;p&gt;There are several different approaches to making this more DRY: &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;.forEach&lt;/code&gt;, &lt;code&gt;.reduce&lt;/code&gt;, etc. I'm going to use the &lt;code&gt;.reduce&lt;/code&gt; Array method, because it processes an array and transforms it into something else (in our case, an object). We're going to use &lt;code&gt;.reduce&lt;/code&gt; three times, once per categorization.&lt;/p&gt;

&lt;p&gt;Let's start by declaring our categories as constants. In the future, we only need to add a new year to our &lt;code&gt;years&lt;/code&gt; array. The code we're about to write will take care of the rest.&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;types&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="s1"&gt;in&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="s1"&gt;out&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;years&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2017&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;regions&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="s1"&gt;Africa&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="s1"&gt;Americas&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="s1"&gt;Asia&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="s1"&gt;Europe&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="s1"&gt;Oceania&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rather than thinking about this as types → years → regions, we want to reverse it and start with regions. Once &lt;code&gt;regions&lt;/code&gt; is turned into an object, that object will be the value assigned to the years properties. The same is true for years in types as well. Note that it's possible to write this in fewer lines of code, but I'm opting for clarity over cleverness.&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;types&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="s1"&gt;in&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="s1"&gt;out&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;years&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2005&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2016&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2017&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;regions&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="s1"&gt;Africa&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="s1"&gt;Americas&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="s1"&gt;Asia&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="s1"&gt;Europe&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="s1"&gt;Oceania&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="cm"&gt;/*
      Convert regions to an object with each region as a property and 
      the region's value as an empty array.
    */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regionsObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regions&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;region&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;acc&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="c1"&gt;// The initial value of the accumulator (`acc`) is set to `{}`. &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;regionsObj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// {Africa: [], Americas: [], Asia: [], Europe: [], Oceania: []}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our regions object, we can do something similar for the years and types. But instead of setting their values to an empty array like we did for the regions, we set their values to the previous category's object.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; It was brought to my attention that the original code snippet didn't actually work once you attempted to load data into it because I was merely referencing an existing object instead of instantiating a new one. The below snippet has been updated to fix this problem by creating a deep copy of the existing object. An explanation is available in this article on &lt;a href="https://medium.freecodecamp.org/copying-stuff-in-javascript-how-to-differentiate-between-deep-and-shallow-copies-b6d8c1ef09cd"&gt;"How to differentiate between deep and shallow copies in JavaScript"&lt;/a&gt; by Lukas Gisder-Dubé.&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;copyObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/* 
      Do the same thing with the years, but set the value 
      for each year to the regions object.
    */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yearsObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;years&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;year&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;copyObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regionsObj&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="c1"&gt;// One more time for the type. This will return our final object.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;types&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;type&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;copyObj&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yearsObj&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="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;dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// {&lt;/span&gt;
    &lt;span class="c1"&gt;//  in: {2000: {Africa: [], Americas: [],...}, ...},&lt;/span&gt;
    &lt;span class="c1"&gt;//  out: {2000: {Africa: [], Americas: [], ...}, ...}&lt;/span&gt;
    &lt;span class="c1"&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have the same result as my original snippet, but have successfully refactored the existing code snippet to be more readable and maintainable! No more copying and pasting when it comes to adding a new year to the dataset!&lt;/p&gt;

&lt;p&gt;But here's the thing: this method still requires somebody to manually update the year list. And if we're going to be loading data into the object anyway, there's no reason to separately initialize an empty object. The next two refactoring options remove my original code snippet completely and demonstrate how we can use the data directly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aside: Honestly, if I had tried to code this 3 years ago, I probably would have done 3 nested &lt;code&gt;for&lt;/code&gt; loops and been happy with the result. But nested loops can have significant negative performance impacts. This method focuses on each layer of categorization separately, eliminating extraneous looping and improving performance. Edit: Check out &lt;a href="https://dev.to/stecman/comment/a9oj"&gt;this comment&lt;/a&gt; for an example of what this method would look like and a discussion on performance.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: Filtering Directly
&lt;/h2&gt;

&lt;p&gt;Some of you are probably wondering why we're even bothering with grouping our data by category. Based on our data structure, we could use &lt;code&gt;.filter&lt;/code&gt; to return the data we need based on the &lt;code&gt;currentType&lt;/code&gt;, &lt;code&gt;currentYear&lt;/code&gt;, and &lt;code&gt;currentRegion&lt;/code&gt;, like so:&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;/*
      `.filter` will create a new array with all elements that return true
      if they are of the `currentType` and `currentYear`

      `.includes` returns true or false based on if `currentRegions`
      includes the entry's region
    */&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentData&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="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;currentType&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
    &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;currentRegion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this one-liner works great, I wouldn't recommend using it in our case for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every time the user makes a selection, this method will run. Depending on the size of that dataset (remember, it grows every year), there could be a negative impact on performance. Modern browsers are efficient and the performance hit might be minuscule, but if we already know that the user can only select 1 type and 1 year at a time, we can be proactive about improving performance by grouping the data from the beginning.&lt;/li&gt;
&lt;li&gt;This option doesn't give us a list of the available types, years, or regions. If we have those lists, we can use them to dynamically generate the selection UI instead of manually creating (and updating) it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05fww0a68mty3qt8u6fp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05fww0a68mty3qt8u6fp.png" alt="A year dropdown with hard-coded options." width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;
Yep, I hard-coded the selectors too. Every time we add a new year, I have to remember to update both the JS and the HTML.



&lt;h2&gt;
  
  
  Option 3: Data Driven Objects
&lt;/h2&gt;

&lt;p&gt;We can combine aspects of the first and second options to refactor the code in a third way. The goal is to not have to change the code at all when updating the dataset, but determine the categories from the data itself.&lt;/p&gt;

&lt;p&gt;Again, there are multiple technical ways to achieve this, but I'm going to stick with &lt;code&gt;.reduce&lt;/code&gt; because we're going to transform our array of data into an object.&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;dataset&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="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;curr&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="cm"&gt;/*
          If the current type exists as a property of our accumulator,
          set it equal to itself. Otherwise, set it equal to an empty object.
        */&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="c1"&gt;// Treat the year layer the same way&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that I've eliminated the region layer of categorization from my dataset object. Because unlike type and year, multiple regions can be selected at once in any combination. This makes pre-grouping into regions virtually useless since we have to merge them together anyway.&lt;/p&gt;

&lt;p&gt;With that in mind, here is the updated one-liner to get the &lt;code&gt;currentData&lt;/code&gt; based on the selected type, year, and regions. Since we're limiting the lookup to data with the current type and year, we know that the maximum number of items in array is the number of countries (less than 200), making this far more efficient than option #2's implementation of &lt;code&gt;.filter&lt;/code&gt;.&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;let&lt;/span&gt; &lt;span class="nx"&gt;currentData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentType&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;currentYear&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;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentRegions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last step is getting the array of the different types, years, and regions. For that, I like to use &lt;code&gt;.map&lt;/code&gt; and Sets. Below is an example of how to get an array that contains all the &lt;em&gt;unique&lt;/em&gt; regions in the data.&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;/*
      `.map` will extract the specified object property 
      value (eg. regions) into a new array
    */&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;regions&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="cm"&gt;/*
        By definition, a value in a Set must be unique.
        Duplicate values are excluded. 
    */&lt;/span&gt;
    &lt;span class="nx"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Array.from creates a new array from the Set&lt;/span&gt;
    &lt;span class="nx"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// One-line version&lt;/span&gt;
    &lt;span class="nx"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="c1"&gt;// or using the spread operator&lt;/span&gt;
    &lt;span class="nx"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repeat for type &amp;amp; year to create those arrays. You can then create the filtering UI dynamically based on the array values.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Refactored Code
&lt;/h3&gt;

&lt;p&gt;Putting it all together, we end up with code that is future-proofed to changes in the dataset. No manual updates required!&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;// Unique Types, Years, and Regions&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&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;years&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&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;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="c1"&gt;// Group data according to type and year&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataset&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="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;curr&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&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;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&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="c1"&gt;// Update current dataset based on selection&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentType&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;currentYear&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;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentRegions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Cleaning up syntax is only a small part of refactoring, but often "refactoring code" really means reconceptualizing the implementation or relationship between different pieces. Refactoring is hard because there are several ways to solve problems. Once you've figured out a solution that works, it can be hard to think of different ones. Determining which solution is better is not always obvious, and can vary based on the code context and frankly, personal preference.&lt;/p&gt;

&lt;p&gt;My advice to getting better at refactoring is simple: read more code. If you're on a team, actively participate in code reviews. If you're asked to refactor something, ask &lt;em&gt;why&lt;/em&gt; and try to understand how others approach problems. If you're working alone (as I was when I first started), pay attention when different solutions are offered to the same question and seek out guides on best code practices. I highly recommend reading &lt;a href="https://basecodefieldguide.com/"&gt;BaseCode&lt;/a&gt; by &lt;a href="https://dev.to/gonedark"&gt;Jason McCreary&lt;/a&gt;. It's an excellent field guide to writing less complex and more readable code, and covers a lot of real world examples.&lt;/p&gt;

&lt;p&gt;Most importantly, accept that you're going to write bad code sometimes and going through the process of refactoring - making it better - is a sign of growth and should be celebrated.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>es6</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Supported, Jacque Coded</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Fri, 08 Mar 2019 21:49:06 +0000</pubDate>
      <link>https://dev.to/jnschrag/supported-jacque-coded--486g</link>
      <guid>https://dev.to/jnschrag/supported-jacque-coded--486g</guid>
      <description>&lt;p&gt;There are so many people sharing their stories today about the harassment they've received and the doubt (both self and externally generated) they have about being in the field. In spite of it all, they continue to do incredible things and persevere.&lt;/p&gt;

&lt;p&gt;Today, I am reminded that my experience as a woman in tech has been different than others.&lt;/p&gt;

&lt;p&gt;My development team is made up 3 women (myself included).&lt;/p&gt;

&lt;p&gt;My entire team is made up of 15 people. 13 of them, including most of the leadership are women.&lt;/p&gt;

&lt;p&gt;My online interactions have largely been positive. I do not receive unsolicited comments on my appearance. My expertise or position on a technical topic has rarely been questioned or dismissed because of my gender.&lt;/p&gt;

&lt;p&gt;But I've seen the harassment and abuse that the women in my community endure on a regular basis. I've heard their stories of being isolated or overlooked in professional settings. I've seen them be questioned about those experiences, and disregarded because "there's no way that happens" to women.&lt;/p&gt;

&lt;p&gt;Those experiences are very, very real. I &lt;em&gt;wish&lt;/em&gt; my experience was the norm, and that more women were truly supported by their colleagues and their communities. &lt;/p&gt;

&lt;h2&gt;
  
  
  So I will continue to code in 2019 because...
&lt;/h2&gt;

&lt;p&gt;I want to make the larger tech community more like my own. Continuing to code and actively engaging with all of the wonderful content produced by other women is the best way I know how to do that. I will continue to offer support and encouragement to them, because I am totally inspired by them on a daily basis. I'm so grateful that they continue to be a part of the community and produce amazing content we can all learn from, even when their experiences are sometimes impossibly difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  I hope to see the tech community...
&lt;/h2&gt;

&lt;p&gt;Help me make my experience the norm, so all women can feel as supported as I have felt in this field. So all women can continue to grow and learn and make mistakes without fear of being targeted and held back because of their gender.&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
    <item>
      <title>10 Lessons Learned Conducting Code Reviews</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Wed, 06 Mar 2019 14:36:14 +0000</pubDate>
      <link>https://dev.to/jnschrag/10-lessons-learned-conducting-code-reviews-5di6</link>
      <guid>https://dev.to/jnschrag/10-lessons-learned-conducting-code-reviews-5di6</guid>
      <description>&lt;p&gt;Last fall, my development team grew from 1 person (me) to 3. Proper pull requests and code reviews all of a sudden became critically important to ensure we had a cohesive codebase after multiple developers from wildly different backgrounds had worked on it.&lt;/p&gt;

&lt;p&gt;As the Lead Developer on the team, I was the primary person responsible for conducting these reviews. Having never done this before, there was a lot for me to learn about making these reviews effective. Here are &lt;strong&gt;#10&lt;/strong&gt; tips and lessons learned from my experience doing code reviews over the past several months.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Always Start with a Positive
&lt;/h2&gt;

&lt;p&gt;Sometimes, there’s a lot wrong with a PR: the right elements weren't used, the implemented design doesn't match the mockups, the logic doesn't make sense, etc. As a reviewer, your job is to look for these kind of mistakes and point them out to be corrected, and it can be easy to only focus on those negatives.&lt;/p&gt;

&lt;p&gt;But nobody intentionally makes mistakes, so having those mistakes pointed out publicly can be a negative, uncomfortable experience. Writing out all those mistakes isn't fun for the reviewer either. To set a positive tone, I've learned to always start my reviews with gratitude and something I thought they did well. Even if there are a lot of issues with the code that need to be addressed, it's important to thank the person for their contribution. Code with mistakes is better than no code at all, so thank them for taking a first pass at resolving the issue.&lt;/p&gt;

&lt;p&gt;If code isn't mentioned in a review, it is generally assumed to be good, but being active with your praise goes a long way. It builds confidence and makes people more receptive to feedback because they know you've spent time thoroughly checking their code. If their logic for X wasn't so great, but they did Y and Z well, let them know!&lt;/p&gt;

&lt;h2&gt;
  
  
  2. It's not "you", it's "the code"
&lt;/h2&gt;

&lt;p&gt;If you've ever learned about conflict resolution, you've probably learned the importance of "I" statements. Using phrases like "I think...", "I feel..." instead of "You did..." can go a long way in resolving tension and shifting the focus from an individual to the problem itself.&lt;/p&gt;

&lt;p&gt;The same approach should be applied to code reviews. When offering criticism, it's important to avoid the word "you". It's already difficult to accept criticism of your work, so don't make it harder by making the person feel like it's &lt;em&gt;them&lt;/em&gt; who are wrong. For example, switching&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your logic on line #25 isn't clear.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The logic on line #25 isn't clear to me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;changes the tone of the comment completely. And I know which one I'd rather read when it's my code being reviewed.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use Line Item Suggestions
&lt;/h2&gt;

&lt;p&gt;My team uses GitHub for most of our projects, and one of my favorite features is the ability to post a comment about a specific line of code. It takes away a lot of the hassle and potential confusion that comes from writing out the specific file/line number in a larger comment. If most of your comments are single changes, this can help make a simple checklist of fixes that need to be made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus: GitHub has line item suggestions. Check out &lt;a class="comment-mentioned-user" href="https://dev.to/_darrenburns"&gt;@_darrenburns&lt;/a&gt;
 &lt;a href="https://dev.to/_darrenburns/8-productivity-tips-for-github-44kn"&gt;"8 Productivity Tips for GitHub"&lt;/a&gt; for details.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you use a different platform that doesn't offer this feature, then I highly recommend including/linking to the specific line numbers when writing your review. It might be more work for you as the reviewer, but it will help ensure those necessary changes aren't overlooked.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Set Project Standards Early &amp;amp; Tools to Help Review
&lt;/h2&gt;

&lt;p&gt;We all learn how and prefer to write code differently. When I was the sole developer, I never had to worry about things like code style, naming conventions, or other project standards because however &lt;em&gt;I&lt;/em&gt; did it was the "right" way. I realized very, very quickly when I started to review other people's code that not everyone had the same internal standards as me and that not only led to confusion in the codebase, but required a bunch of extra mental energy for me to review.&lt;/p&gt;

&lt;p&gt;The lesson learned here is simple: set your project standards early.&lt;/p&gt;

&lt;p&gt;Whatever those standards are, it's important that the whole team is on board with them and knows what is expected. And you need them for everything: languages being used, branch naming conventions, project organization, comment conventions, etc.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aside: This process made me realize I had strong opinions about CSS property order, so I made a point to address that in our discussion.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Whether you develop your own standards in-house or use one of the many existing standards out there is up to you, but it's &lt;strong&gt;critically&lt;/strong&gt; important that you do if you want to have any semblance of a cohesive codebase at the end of a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools to Help Review
&lt;/h3&gt;

&lt;p&gt;Once you have your project standards, it's worth spending the time to set up the tools that are designed specifically to help enforce those standards. You can use a Linter to analyze your code and compare it against a set of guidelines for syntax-related standards. It will flag any errors, or can possibly even fix them for you automatically.&lt;/p&gt;

&lt;p&gt;To catch any errors that make it into the PR (although ideally, they're caught and dealt with locally first), we've set up TravisCI to run additional checks. So if the Travis build is failing when I go to review, it gives me a place to start before diving deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Start Broad &amp;amp; then Dig Into Details
&lt;/h2&gt;

&lt;p&gt;There can be a lot of code in a single pull request, so in terms of actually doing the code review, I like to start broadly and work my way into the nitty-gritty. For me, that process usually looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Are there any failing tests? If yes, why are they failing?&lt;/li&gt;
&lt;li&gt;Are there any extra files included in the PR that shouldn't be there?&lt;/li&gt;
&lt;li&gt;Can I checkout the branch without any errors?&lt;/li&gt;
&lt;li&gt;Was any relevant documentation updated to reflect the changes?&lt;/li&gt;
&lt;li&gt;Were new packages or dependencies added to the project? If yes, why were they added? Are they needed?&lt;/li&gt;
&lt;li&gt;Is the HTML valid, semantic, and accessible?&lt;/li&gt;
&lt;li&gt;Does the CSS follow the project standards? Are all viewport widths accounted for in the implementation? What about cross-browser compatibility?&lt;/li&gt;
&lt;li&gt;Does the JavaScript follow the project standards? Is it modular? Is it easy to follow the logic? Are edge cases accounted for? Are there stray logs in the console?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If there are a lot of issues in the first few steps, I usually end my review there and wait for those issues to be addressed before digging into the denser part of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Establish Dedicated Review Time
&lt;/h2&gt;

&lt;p&gt;This has been one of the hardest lessons for me to learn, and is something that I still actively struggle with. Doing a thorough and productive code review takes &lt;em&gt;time&lt;/em&gt;. Even if the PR is small, it still (usually) requires checking out the branch, checking the logic, reviewing the issue, etc. When you have other competing priorities, it  can be tempting to ignore that pull request or do the bare minimum when reviewing, but that isn't a good long-term solution.&lt;/p&gt;

&lt;p&gt;My solution to this was fairly straightforward: I have a dedicated time when I do reviews. I block it on my calendar and my team knows when those times are so they know when to expect feedback. Setting expectations for your team and yourself is key.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Establish What You're Expecting
&lt;/h2&gt;

&lt;p&gt;Do you link your pull requests to issues? Require a certain format when submitting a pull request? Have a limit to how many lines of code should be included in a single request?&lt;/p&gt;

&lt;p&gt;If you answered yes to any of these questions, then it's important to establish those expectations up front. It saves you time as the reviewer and helps prevent your team from having to guess what it is that you're looking for. Take the time to talk to your team and figure out what works best for all of you because...&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Everyone Reviews
&lt;/h2&gt;

&lt;p&gt;On our team, everyone has the opportunity to do code reviews and everyone has their code reviewed. As the senior developer on the team, my pull requests are reviewed by the two other members before they can be merged. I do this because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;My code has mistakes and often can be improved, and&lt;/li&gt;
&lt;li&gt;It creates space for the more junior devs to ask questions about how/why I implemented something the way that I did.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm a big-believer in that the best way to learn how to code well is to read well-written code, so even if there is nothing to change, it allows them to read good code examples that are relevant to the project they are working on. We frequently have good conversations about implementation in our code reviews, and it's made me more confident in my decisions when I'm able to answer questions about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Reevaluate Often
&lt;/h2&gt;

&lt;p&gt;Conducting code reviews has been one big learning process for me and for our team. We've made a lot of changes along the way based on our experience. It's important to carve out time to reflect on this aspect of the project; I usually do it as a part of a broader post-mortem on a project which helps solidify code reviews as a critical part of the development process.&lt;/p&gt;

&lt;p&gt;Ask what worked well and what doesn't, and be honest with the answers! Ask your team members what kind of feedback they found helpful or identify areas where the critique can be improved. Consider how much time you spent doing reviews and identify any patterns from it. If you were frequently commenting on the same types of issues, are there steps you can take to address it so there are less of those issues on the next project? Reflecting on these types of questions and making changes will improve the review process for everyone on the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. There's more than One Solution
&lt;/h2&gt;

&lt;p&gt;This one is hard. Really hard. When you are the reviewer, it can be so tempting to start refactoring the submitter's code to reflect how &lt;em&gt;you&lt;/em&gt; would have done it. What starts out as a simple refactor can very easily turn into redoing the entire section of code to your "right" solution. But that isn't the purpose of a code review.&lt;/p&gt;

&lt;p&gt;It's a fine line, to be sure. Sometimes the code does genuinely need to be reimagined and fully rewritten, but that should not be happening frequently. If it does, then a better approach would be to pair program before the code review stage.&lt;/p&gt;

&lt;p&gt;But just because it isn't how you would have approached and solved the problem, doesn't mean it isn't good. When you open a pull request and start the review, you need to check your ego at the door and be open minded to considering new solutions. Use it as an opportunity to learn, not show off how smart you think you are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus: &lt;a class="comment-mentioned-user" href="https://dev.to/maxwell_dev"&gt;@maxwell_dev&lt;/a&gt;
 wrote a brilliant post on &lt;a href="https://dev.to/maxwell_dev/its-not-about-you-53h3"&gt;"It's Not About You"&lt;/a&gt; that addresses this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's been a journey learning all of this, and I'm grateful to my team for their continued patience while I've figured it out. In the nature of continued learning and reevaluating often (#9!), what are some of your tips for conducting code reviews?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>codereview</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>How do you keep track of what you're reading?</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Wed, 18 Jul 2018 14:08:43 +0000</pubDate>
      <link>https://dev.to/jnschrag/how-do-you-keep-track-of-what-youre-reading-od4</link>
      <guid>https://dev.to/jnschrag/how-do-you-keep-track-of-what-youre-reading-od4</guid>
      <description>&lt;p&gt;One of my New Year's resolutions was to try and take better notes on the various articles and books that I read related to development. I'm one of those people that needs to write things down if I'm going to remember it later. With so much helpful content being written on a regular basis, it can get overwhelming keeping track of what I've read and what the key points I want to remember were.&lt;/p&gt;

&lt;p&gt;My current solution is to use &lt;a href="https://boostnote.io/"&gt;Boostnote&lt;/a&gt; as a note taking app. Every day, I create a new note and post the links and my summaries of the articles for that day, tagged according to the topics.&lt;/p&gt;

&lt;p&gt;How do you keep track of what you've read? Tools, methods, etc.?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Nevertheless, Jacque Schrag Coded</title>
      <dc:creator>Jacque Schrag</dc:creator>
      <pubDate>Fri, 02 Mar 2018 21:25:36 +0000</pubDate>
      <link>https://dev.to/jnschrag/nevertheless-jacque-schrag-coded--1ml1</link>
      <guid>https://dev.to/jnschrag/nevertheless-jacque-schrag-coded--1ml1</guid>
      <description>&lt;h2&gt;
  
  
  I began to code because...
&lt;/h2&gt;

&lt;p&gt;when I was in elementary school, my dad went back to school so he could become a web developer. For Christmas that year, he gave me his HTML4 reference book when I started asking questions about &lt;em&gt;how&lt;/em&gt; he was making websites. I started reading and never looked back. Although it has always been a passion hobby of mine, coding did not become something I considered doing professionally until graduate school when I realized that there was a serious need in the policy sphere for web development. I've been fortunate enough to be able to create a position for myself where I can work on topics I care about and build cool web projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  I recently overcame...
&lt;/h2&gt;

&lt;p&gt;shyness about sharing my work and participating in development communities. Imposter syndrome is incredibly real and has been a frustrating aspect of getting into this career. I hope to be a more active member of the communities I'm in and not just lurk on the sidelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  I want to brag about...
&lt;/h2&gt;

&lt;p&gt;the team I work on. We're an award-winning creative agency inside of a think tank and are producing some really cool stuff. We're also (almost) an entirely women team, which is a rarity in both the tech and think tank spheres. I love coming to work and feeling inspired everyday by the work my colleagues do and it gives me courage to keep working even when the feeling of imposter syndrome becomes overwhelming.&lt;/p&gt;

&lt;h2&gt;
  
  
  My advice for allies to support women who code is....
&lt;/h2&gt;

&lt;p&gt;be vocal about your support and be vulnerable about the things you struggle with. Knowing that there is somebody else out there who feels just as lost when they look at the state of the JavaScript ecosystem (seriously though - I &lt;em&gt;finally&lt;/em&gt; got a handle on Webpack 3) can mean everything when you're questioning whether or not you have the skills to make it in the field.&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
  </channel>
</rss>
