<?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>Forem: Ezell Frazier</title>
    <description>The latest articles on Forem by Ezell Frazier (@_ezell_).</description>
    <link>https://forem.com/_ezell_</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%2F215655%2Fcf682768-f1c2-4094-82c8-bd2a5287c146.jpg</url>
      <title>Forem: Ezell Frazier</title>
      <link>https://forem.com/_ezell_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/_ezell_"/>
    <language>en</language>
    <item>
      <title>How to Upload Files in 2022?</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Fri, 03 Jun 2022 18:34:28 +0000</pubDate>
      <link>https://forem.com/_ezell_/how-to-upload-files-in-2022-ile</link>
      <guid>https://forem.com/_ezell_/how-to-upload-files-in-2022-ile</guid>
      <description>&lt;h2&gt;
  
  
  Can we finally do away with the Input Element and FileReader API?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This post involves the context of handling and reading files within a JavaScript-based web application. There's nothing wrong with using an input element for file uploads for other purposes. However, it's wonderful to have an alternative approach. &lt;/p&gt;

&lt;h3&gt;
  
  
  The Old Way of Uploading Files with JavaScript
&lt;/h3&gt;

&lt;p&gt;So, I'm writing an application and I want to allow for users to save and load their configurations. JSON is likely the simplest approach here. Or, I'd think.&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;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;".json"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"upload"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;uploadElement&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;upload&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;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Two event handlers to for uploading and reading files&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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="nx"&gt;uploadElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;The old approach involves declaring two input handlers for two asynchronous operations. The reader object can read uploaded files, however &lt;code&gt;reader.result&lt;/code&gt; is not available in a traditional sequence, as seen below:&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;uploadElement&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;upload&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;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;uploadElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// why is this null?&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;reader.result&lt;/code&gt; is null because it hasn't finished reading the file. So, a workaround involves using the reader's &lt;code&gt;readAsText&lt;/code&gt; method in tandem with a &lt;code&gt;Promise&lt;/code&gt; constructor.&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;uploadElement&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upload&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;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Poll for changes to the filereader's state about every 25ms&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;readTextAsync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filereader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileBlob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;filereader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setInterval&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;filereader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DONE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filereader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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;25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;uploadElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;readTextAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&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="nx"&gt;log&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="c1"&gt;// We have our json string&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no longer two event handlers, but there's more code.&lt;/p&gt;

&lt;p&gt;Converting callback-based APIs into something more modern may be  more tedious to write, harder to read, and possibly introduce more opportunities for bugs. Thankfully, we can use the recently introduced &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API"&gt;File System Access API&lt;/a&gt; to tackle this problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uploading files with the File System Access API
&lt;/h3&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;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"upload"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Select a File&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;uploadBtn&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="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// I can clearly see and understand what's happening here&lt;/span&gt;
&lt;span class="nx"&gt;uploadBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;types&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="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&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;application/json&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.json&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="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fileHandle&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showOpenFilePicker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fileHandle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFile&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;file&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's many improvements to the developer experience here. &lt;code&gt;window.showOpenFilePicker&lt;/code&gt; allows us to place the following all in one callback function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File reading&lt;/li&gt;
&lt;li&gt;File parsing&lt;/li&gt;
&lt;li&gt;File Picker Options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the biggest benefit is not having tightly related implementation details within multiple places across multiple files, across multiple steps.&lt;/p&gt;

&lt;p&gt;Lastly, the &lt;code&gt;input&lt;/code&gt; element may introduce a design which clashes with the overall theme of the UI. It's not uncommon to see implementations of a button element for file uploading, while hiding the actual &lt;code&gt;input&lt;/code&gt; element responsible for the file upload. &lt;/p&gt;

&lt;p&gt;None of that is required here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caveats
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The File System Access API is fully supported within Chrome and Edge browsers as of this post. &lt;a href="https://github.com/GoogleChromeLabs/browser-fs-access"&gt;However, Polyfills are available&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The FileSystem API only works in secure, &lt;code&gt;https://&lt;/code&gt; environments, with the exception of &lt;code&gt;localhost&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The FileSystem API also won't work within iframes or other framed environments like CodePen / CodeSandbox, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API"&gt;Learn more about the File System Access API on MDN&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>When is onChange not the same as onChange?</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Thu, 10 Mar 2022 17:38:07 +0000</pubDate>
      <link>https://forem.com/_ezell_/when-is-onchange-is-not-the-same-as-onchange-3i3e</link>
      <guid>https://forem.com/_ezell_/when-is-onchange-is-not-the-same-as-onchange-3i3e</guid>
      <description>&lt;p&gt;A colleague raised a fair question, &lt;em&gt;why doesn’t an input element's onchange event type behave the same as React’s onChange?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wait, what do you mean?&lt;/em&gt;, was my initial thought not realizing the inherent difference between the two.&lt;/p&gt;

&lt;p&gt;Digging deeper into the question uncovered what could be a jarring experience for a developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we’d expect?🤔
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The native web API &lt;code&gt;onchange&lt;/code&gt; attribute
&lt;/h3&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;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;“text”&lt;/span&gt; &lt;span class="na"&gt;onchange=&lt;/span&gt;&lt;span class="s"&gt;“console.log(‘changed’)”&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When do we expect the string &lt;em&gt;changed&lt;/em&gt; to appear in the console? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After a user presses a key?&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event"&gt;After the user changes focus from the input element? ✅&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;After the last key is pressed?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  React's &lt;code&gt;onChange&lt;/code&gt; prop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;changed&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think we know what happens here. &lt;/p&gt;

&lt;p&gt;The string appears in the console each time the user &lt;em&gt;inputs&lt;/em&gt; a new value.&lt;/p&gt;

&lt;p&gt;The two event types behave differently by design. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/docs/dom-elements.html#onchange"&gt;The React team believes this is how the native &lt;code&gt;onchange&lt;/code&gt; should behave.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever the element's value has &lt;em&gt;changed&lt;/em&gt;, the corresponding event should fire.&lt;/p&gt;

&lt;p&gt;But wait, don't we already have an event type for that? &lt;/p&gt;

&lt;h2&gt;
  
  
  The input event
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The native web API &lt;code&gt;oninput&lt;/code&gt; attribute
&lt;/h3&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;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;“text”&lt;/span&gt; &lt;span class="na"&gt;oninput=&lt;/span&gt;&lt;span class="s"&gt;“console.log(‘changed’)”&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  React's &lt;code&gt;onInput&lt;/code&gt; prop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt; &lt;span class="na"&gt;onInput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;changed&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, both React and the web API behave the same, or &lt;em&gt;as we'd expect&lt;/em&gt;. The string appears in the console when the user changes the element's value. &lt;/p&gt;

&lt;p&gt;So, shouldn't we leverage &lt;code&gt;onInput&lt;/code&gt; instead of &lt;code&gt;onChange&lt;/code&gt;? Well, that's likely the way to go if one's working with other JSX-based frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  When &lt;code&gt;onChange&lt;/code&gt; isn't &lt;code&gt;onChange&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Stencil.js is a neat framework for building web components. Like React, Stencil uses JSX for markup. &lt;a href="https://stenciljs.com/docs/forms"&gt;And if we wanted to use React's &lt;code&gt;onChange&lt;/code&gt; behavior, we'd instead need to use &lt;code&gt;onInput&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solid.js, a newer web framework which draws inspiration from React, can also use JSX for markup. &lt;a href="https://www.solidjs.com/docs/latest"&gt;And like Stencil.js, &lt;code&gt;onChange&lt;/code&gt; behaves like the native web implementation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if one were to migrate some JSX from one framework to another, note that React's subtle opinion may not carry over.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;oninput&lt;/code&gt; may also be a good choice if one wants to avoid the &lt;code&gt;onchange&lt;/code&gt; trap altogether. 👀&lt;/p&gt;

</description>
      <category>react</category>
      <category>solidjs</category>
      <category>stenciljs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Why Doesn't React's useState Hook Merge Objects?</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Wed, 09 Mar 2022 15:18:00 +0000</pubDate>
      <link>https://forem.com/_ezell_/why-doesnt-reacts-usestate-hook-merge-objects-8h3</link>
      <guid>https://forem.com/_ezell_/why-doesnt-reacts-usestate-hook-merge-objects-8h3</guid>
      <description>&lt;p&gt;I saw a question today about React's &lt;code&gt;useState&lt;/code&gt; hook, as there is &lt;em&gt;unexpected behavior&lt;/em&gt; compared to &lt;code&gt;this.setState&lt;/code&gt; in class components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expected Behavior
&lt;/h3&gt;

&lt;p&gt;A user inputs a value and &lt;code&gt;this.setState&lt;/code&gt; &lt;em&gt;merges&lt;/em&gt; both initial state and the dispatched object from the event handler. &lt;/p&gt;

&lt;p&gt;So, if a user types the letter &lt;code&gt;a&lt;/code&gt;, state is represented as the merger of, &lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ name: 'a' }&lt;/code&gt; and &lt;code&gt;{ name: '', email: '', phone: '' }&lt;/code&gt;, &lt;/p&gt;

&lt;p&gt;as &lt;code&gt;{ name: 'a', email: '', phone: '' }&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ControlledForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;phone&lt;/span&gt;&lt;span class="p"&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="nx"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;fieldset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onInput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="si"&gt;}&lt;/span&gt; 
            &lt;span class="c1"&gt;// { name: 'a', email: '', phone: '' }&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;fieldset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&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;h3&gt;
  
  
  Unexpected Behavior?
&lt;/h3&gt;

&lt;p&gt;A user inputs a value as before. However, &lt;code&gt;setFormValues&lt;/code&gt; dispatches an object,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ name: 'a' }&lt;/code&gt;, replacing the initial state object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ControlledForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;formValues&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFormValues&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;fieldset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
          &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="c1"&gt;// { name: 'a' }&lt;/span&gt;
          &lt;span class="na"&gt;onInput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setFormValues&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;fieldset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Manually Merging Objects
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;setState&lt;/code&gt; or &lt;code&gt;setFormValues&lt;/code&gt; in this context, is a function with a parameter that can be a plain value, an object, or a function with a parameter containing its current state. &lt;/p&gt;

&lt;p&gt;We can leverage the function parameter to merge our objects (or arrays).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formValues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// { name: 'a', email: '', phone: '' }&lt;/span&gt;
  &lt;span class="na"&gt;onInput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setFormValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&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="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="si"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why though?
&lt;/h3&gt;

&lt;p&gt;This may feel like a jarring developer experience for those migrating from legacy React code but, &lt;a href="https://reactjs.org/docs/hooks-faq.html#should-i-use-one-or-many-state-variables"&gt;this is by design&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you miss automatic merging, you could write a custom useLegacyState Hook that merges object state updates. &lt;strong&gt;However, we recommend to split state into multiple state variables based on which values tend to change together&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, it may be more convenient to avoid merging objects altogether. Would one need to merge objects if replacing the previous object achieved the same result? &lt;/p&gt;

&lt;p&gt;So, if one has to merge state objects, they have a few options at their disposal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual merging of objects within state&lt;/li&gt;
&lt;li&gt;Individual &lt;code&gt;useState&lt;/code&gt; hooks for each object property&lt;/li&gt;
&lt;li&gt;A reducer (which may be a tad too much for this example)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When working with state, I tend to ask myself, do these variables change together? If yes, I'll go with an object, and know I'll be fine. &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Low Cost Value-Adds for Any React Project</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Mon, 07 Feb 2022 15:03:56 +0000</pubDate>
      <link>https://forem.com/_ezell_/low-cost-value-adds-for-any-react-project-103k</link>
      <guid>https://forem.com/_ezell_/low-cost-value-adds-for-any-react-project-103k</guid>
      <description>&lt;p&gt;Landed a new role? New to a React project? Just want to see if there's anything new here? &lt;/p&gt;

&lt;p&gt;Here are a few ways to hit the ground running with minimal cost to existing codebases. Free of any package installations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default Props
&lt;/h2&gt;

&lt;p&gt;It is not uncommon to discover legacy or current React codebases with components containing no default values for the props it consumes. Which implies the value &lt;code&gt;undefined&lt;/code&gt; is part of expected behavior, which is risky business.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// What should we see if the message prop isn't provided?&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://reactjs.org/docs/react-component.html#defaultprops"&gt;Leveraging React's defaultProps component property&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Greeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No message prop provided!&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;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment"&gt;Using Object Destructuring Assignment&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No message prop provided!&lt;/span&gt;&lt;span class="dl"&gt;'&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding TypeScript Types via &lt;a href="https://jsdoc.app/"&gt;JSDoc&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;It's safe to assume numerous React developers are using Visual Studio Code as their text editor. Why not enhance the development experience by leveraging VSCode's Intellisense?&lt;/p&gt;

&lt;p&gt;Adding types via React Prop Types or TypeScript may face some resistance, but it doesn't mean we can't use types with comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @description defaults to "No message prop provided!"
 * @param {{ message: string }} { message }
 * @returns {JSX.Element} Greeting component
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No message prop provided!&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&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;&lt;a href="https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html"&gt;Learn more Here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanatory Comments
&lt;/h2&gt;

&lt;p&gt;I admit, this is a piece of advice for myself as much as it is for anyone else. Also, this is a general good habit for any project.&lt;/p&gt;

&lt;p&gt;Ideally, we want to write comments explaining why we're adding a component or a highly re-used module. &lt;/p&gt;

&lt;p&gt;If we can't explain it in a line, try to include a reference to the ticket. &lt;/p&gt;

&lt;p&gt;Received a hard-to-understand piece of code from the internet? Include a link to where it was found.&lt;/p&gt;

&lt;p&gt;Your teammates and future-self will greatly appreciate this.&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;// Wanted a concise way to compose the props for a hairy view&lt;/span&gt;
&lt;span class="c1"&gt;// See ticket #4207 for details&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fns&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;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&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;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Have any more tips? I'd love to know more! &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Make Any Method Chainable in JavaScript</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Mon, 20 Dec 2021 16:40:37 +0000</pubDate>
      <link>https://forem.com/_ezell_/bringing-back-the-one-thing-i-love-about-jquery-1od0</link>
      <guid>https://forem.com/_ezell_/bringing-back-the-one-thing-i-love-about-jquery-1od0</guid>
      <description>&lt;h3&gt;
  
  
  TLDR;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;jQuery pushed the web and JavaScript forward, but its method chaining is greatly missed&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;What if I told you&lt;/em&gt; ther is a way to bring this back? &lt;/li&gt;
&lt;li&gt;This may be a representation of something that I'm not here to talk about 👀&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Should Anyone Care About This?
&lt;/h3&gt;

&lt;p&gt;Regardless of one's experience with JavaScript, they may have heard of jQuery. During the early-to-mid 2000's, the web had reached a level of maturity allowing developers to create fluid user experiences compared to a collection of web pages. &lt;/p&gt;

&lt;p&gt;But, this was a tedious task given how  &lt;em&gt;bare bones&lt;/em&gt; JavaScript and web browser APIs were compared to other programming languages. Imagine not having &lt;code&gt;fetch&lt;/code&gt; or &lt;code&gt;document.querySelector&lt;/code&gt;. That's pretty rough right? Well, jQuery filled in &lt;em&gt;all the gaps&lt;/em&gt;, and &lt;em&gt;then some&lt;/em&gt;. For some, jQuery was the standard library of client-side web development. But, that was then; &lt;a href="https://github.com/nefe/You-Dont-Need-jQuery"&gt;JavaScript and the web has evolved&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, with all the significant improvements enhancing JavaScript and web APIs, &lt;a href="https://www.w3schools.com/JQuery/jquery_chaining.asp"&gt;jQuery's method chaining was largely left behind&lt;/a&gt;. And because of this, &lt;a href="https://stackoverflow.com/a/11503576/8861695"&gt;jQuery isn't leaving the tool-belt of some developers&lt;/a&gt;. Can one blame them for that? jQuery provided a clean developer experience, while providing tools for building similarly clean user experiences. What's a relatively quick and painless way to bring this back?&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Method Chaining?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&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;#p1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color&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;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;slideUp&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="nx"&gt;slideDown&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chaining methods like &lt;code&gt;.css&lt;/code&gt;, &lt;code&gt;.slideUp&lt;/code&gt;, and &lt;code&gt;slideDown&lt;/code&gt; is highly expressive and concise. &lt;a href="https://en.wikipedia.org/wiki/Fluent_interface#JavaScript"&gt;jQuery's implementation represents a Fluent Interface&lt;/a&gt;, providing a level of &lt;a href="https://stackoverflow.com/a/2427539/8861695"&gt;expressiveness&lt;/a&gt; where code almost reads like  plain English.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wouldn't Native Method Chaining be Neat?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;#p1&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="nx"&gt;setCss&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;height 2s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&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="nx"&gt;setCss&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100px&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;This could be achieved, but &lt;a href="https://stackoverflow.com/questions/28653761/chaining-html5-classlist-api-without-jquery"&gt;one would need to know and care about  implementation details between the DOM and one's app&lt;/a&gt;, which may introduce far more complexity than is required for most use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing Generic Method Chaining with &lt;em&gt;The Box&lt;/em&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p1&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="nx"&gt;modifyContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slideUp&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="nx"&gt;modifyContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slideDown&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100px&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;The objective is to place whatever one wants inside of a &lt;em&gt;Box&lt;/em&gt;. Its two methods &lt;code&gt;replaceContents&lt;/code&gt; and &lt;code&gt;modifyContents&lt;/code&gt; allows one to temporarily take an item outside of the &lt;em&gt;Box&lt;/em&gt;, perform an action, and place it into another &lt;em&gt;Box&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;This approach allows one to have a clear separation between what's desired (method chaining) and what one's already writing (DOM manipulation). Additionally, highly modular, and independent code is easier to compose and test.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// highly modular&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;slideUp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slideDown&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// bring your own implementation details&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Is this Form of Method Chaining Really Generic?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Numbers
&lt;/h4&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;four&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Box&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;four&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;num&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;num&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;modifyContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 8&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ten&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eight&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;num&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;num&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;modifyContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Arrays
&lt;/h4&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;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Box&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;evens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;numArr&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;numArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&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;modifyContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [3, 4, 5, 6, 7]&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sums&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;sums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&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;span class="nx"&gt;modifyContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [4, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Mixed Types (Map, Array)
&lt;/h4&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;gteTo2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;table&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;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceContents&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;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;replaceContents&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&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="nx"&gt;modifyContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Map { 'b' =&amp;gt; 2, 'c' =&amp;gt; 3 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Box&lt;/em&gt; works with any type. Its two methods &lt;code&gt;replaceContents&lt;/code&gt; and &lt;code&gt;modifyContents&lt;/code&gt; have a single parameter, which is whatever item is inside of &lt;em&gt;The Box&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Box&lt;/em&gt; can contain a primitive or an object. The difference between its two methods is that &lt;code&gt;replaceContents&lt;/code&gt; must return a value, and &lt;code&gt;modifyContents&lt;/code&gt; does not. In other words, &lt;code&gt;replaceContents&lt;/code&gt; is great for ensuring immutability.&lt;/p&gt;

&lt;p&gt;Here's the interface for TypeScript or other languages.&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IBox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;replaceContents&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;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;V&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;IBox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;modifyContents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&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;IBox&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;h3&gt;
  
  
  How Does &lt;em&gt;The Box&lt;/em&gt; compare to Fluent Interfaces?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;The Box&lt;/th&gt;
&lt;th&gt;Fluent Interfaces&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Method Chaining&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Highly Expressive&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports immutability&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugger-friendly&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging-friendly&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works with any data type&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module-friendly&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Sold? Here's What &lt;em&gt;The Box&lt;/em&gt; Looks Like
&lt;/h3&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="nx"&gt;Box&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;replaceContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifyContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&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;fn&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Box&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;replaceContents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;modifyContents&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;h3&gt;
  
  
  Wait a Minute, Is &lt;em&gt;The Box&lt;/em&gt; a &lt;a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)"&gt;You-Know-What?&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;👀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>functional</category>
    </item>
    <item>
      <title>Job Descriptions JavaScript Developers Should be Weary of in 2019</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Wed, 25 Sep 2019 00:17:49 +0000</pubDate>
      <link>https://forem.com/_ezell_/job-descriptions-javascript-developers-should-be-weary-of-in-2019-j3a</link>
      <guid>https://forem.com/_ezell_/job-descriptions-javascript-developers-should-be-weary-of-in-2019-j3a</guid>
      <description>&lt;p&gt;Recently, &lt;a href="https://www.reddit.com/r/javascript/comments/d8goc2/askjs_can_we_stop_treating_es2015_features_as_new/"&gt;a thread over at r/javascript&lt;/a&gt; has me a bit fired up.&lt;/p&gt;

&lt;p&gt;JavaScript today is not JavaScript of 2006, 2004, or prior. I repeat.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Modern JavaScript is not "just" JavaScript&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recruiters, and HR, please take note.&lt;/p&gt;

&lt;p&gt;Lead devs,&lt;/p&gt;

&lt;p&gt;I understand this language may have burned you, chewed you up, and made your life utterly miserable a decade ago. &lt;/p&gt;

&lt;p&gt;This is not an acceptable excuse for attempting to hire a developer and stagnating their career progression with your outdated tech stack. &lt;/p&gt;

&lt;p&gt;If Internet Explorer 11 and below are a required target, you better prepare to offer higher compensation for outdated technology.&lt;/p&gt;

&lt;p&gt;Junior devs to-be,&lt;/p&gt;

&lt;p&gt;Please take in consideration of where you see yourself in the future. If you've been building applications with technologies such as Ember, React, Angular, and Vue, please be cautious of job listings containing jQuery or "JavaScript" with no context.&lt;/p&gt;

&lt;p&gt;If you are working heavily with ES2015 syntax and front-end frameworks, you are no longer just a 'front-end web developer'. You are an application developer. Don't let anyone try to cut corners with job descriptions.&lt;/p&gt;

&lt;p&gt;However, job descriptions are just the beginning. You need to press the topic during the interviewing process if you have any doubt.&lt;/p&gt;

&lt;p&gt;Legacy code is real, and you need to ask if you'll be spending 90% of your time in jQuery-land or what you thought you signed up for instead. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"I saw jQuery and React on the job posting, are you transitioning to React"?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"The interview question/tests are using some older syntax, is this indicative of your current codebase"?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyways, I scoured a job board to find a list of good and questionable job descriptions. Notice a common key-word in each of the good descriptions. If there is no mention of ES2015 (ES6) or higher, then you need to go on the offensive during the interviewing process. &lt;/p&gt;

&lt;h2&gt;
  
  
  Good Job Descriptions
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Senior Level&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Expert level programming knowledge in Javascript (ES6), including writing cross-browser code, writing testable code.&lt;/li&gt;
&lt;li&gt;Knowledge of best practices &amp;amp; patterns for large scale applications in javascript .&lt;/li&gt;
&lt;li&gt;Efficient DOM manipulation.&lt;/li&gt;
&lt;li&gt;Component architecture using AngularJS or ReactJS/Redux. &lt;/li&gt;
&lt;li&gt;Less dependent on third party ibraries.&lt;/li&gt;
&lt;li&gt;Web: HTML(5), CSS(3), BootStrap/Foundation,&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Intermediate Level&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;2+ years of professional JavaScript experience, including concepts like asynchronous programming, closures, types, and ES6&lt;/li&gt;
&lt;li&gt;2+ years of professional HTML/CSS experience, including concepts like layout, specificity, cross browser compatibility, and accessibility&lt;/li&gt;
&lt;li&gt;Broad understanding of the JavaScript ecosystem
Experience with React, Angular, Vue.js, or other modern frontend frameworks&lt;/li&gt;
&lt;li&gt;Direct experience with professional software development practices, including coding standards, source control (Git), code reviews, build processes, and testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Junior Level&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Passionate and fast learner&lt;/li&gt;
&lt;li&gt;Knowledge and experience with one or more Javascript frameworks such as AngularJS or React&lt;/li&gt;
&lt;li&gt;Experience and opinions about one or more of the animals in the JavaScript zoo: Webpack, ES6, TypeScript, ClojureScript, Grunt, Elm, Redux&lt;/li&gt;
&lt;li&gt;Expert with HTML5, CSS and modern web design standards&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Questionable Job Descriptions
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Intermediate - Senior Level&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Must have excellent background and understanding of HTML5, CSS3, SVG, ReactJS, Web Socket and Canvasas as well as Client-side Java Script.&lt;/li&gt;
&lt;li&gt;Several client-side frameworks and build tools (ReactJS, jQuery, Less/Sass, Grunt/Gulp, etc).&lt;/li&gt;
&lt;li&gt;Server-side development (JavaScript/Node.js, PHP, etc) and architecture (Apache/Nginx/etc.)&lt;/li&gt;
&lt;li&gt;Database-driven web applications&lt;/li&gt;
&lt;li&gt;REST APIs.&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Bash (linux or Mac)&lt;/li&gt;
&lt;li&gt;Security best practices &amp;amp; familiarity with:&lt;/li&gt;
&lt;li&gt;Relational Databases (SQL &amp;amp; PL/SQL)&lt;/li&gt;
&lt;li&gt;Web Services&lt;/li&gt;
&lt;li&gt;3rd Party APIs: Twitter,Facebook, Google Maps, etc&lt;/li&gt;
&lt;li&gt;Knowledge of common content management systems
iOS and/or Android native development experience a plus&lt;/li&gt;
&lt;li&gt;Comfort with Agile and Waterfall development methodologies&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Intermediate Level&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Minimum of 3 years work experience as a web developer/programmer&lt;/li&gt;
&lt;li&gt;Solid exposure to front-end technologies is required:&lt;/li&gt;
&lt;li&gt;JavaScript-3+ years of experience&lt;/li&gt;
&lt;li&gt;HTML-3+ years of experience&lt;/li&gt;
&lt;li&gt;CSS-3+ years of experience&lt;/li&gt;
&lt;li&gt;PHP-3+ years of experience&lt;/li&gt;
&lt;li&gt;Netsuite SuiteCommerce Development Certification a plus&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Junior-Intermediate Level&lt;/em&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Proficient in HTML5, CSS3, JavaScript/jQuery.
Comfortable writing native JavaScript from scratch.&lt;/li&gt;
&lt;li&gt;Proficient in bootstrap and/or other responsive frameworks.&lt;/li&gt;
&lt;li&gt;WordPress development (Installation, customization, and updating) a must-have.&lt;/li&gt;
&lt;li&gt;Comfortable in Photoshop/Illustrator to slice and create images.
1 – 3 years of experience.&lt;/li&gt;
&lt;li&gt;Bachelors degree in Computer Science or similar, preferred but not required.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>career</category>
    </item>
    <item>
      <title>How to Learn Fast</title>
      <dc:creator>Ezell Frazier</dc:creator>
      <pubDate>Thu, 22 Aug 2019 11:30:23 +0000</pubDate>
      <link>https://forem.com/_ezell_/how-to-learn-fast-2eim</link>
      <guid>https://forem.com/_ezell_/how-to-learn-fast-2eim</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TLDR;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Focus on what you need to know and filter out unrelated information&lt;/li&gt;
&lt;li&gt;How to find out what you need to know? Test what you think you know.&lt;/li&gt;
&lt;li&gt;Summarize everything you think you know about what you've read&lt;/li&gt;
&lt;li&gt;If summarizing what you know is tough, focus on the where you're struggling and repeat the earlier steps.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Does reading a book from cover to cover qualify the book as being &lt;em&gt;read&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Definitely so for fiction.&lt;/p&gt;

&lt;p&gt;How about textbooks? News articles? Tutorials?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I've been doing it wrong for almost three decades.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I didn't catch on until my senior year in college. I graduated from a commuter school, or a school with no campus-life. My grades were slightly above average. Juggling heavy-work hours and being a full-time student was no easy feat.&lt;/p&gt;

&lt;p&gt;In my senior year, I began to wonder, "how"? How are some students able to work 40 to 60-hour workweeks and still ace exams and projects? What's the science? The witchcraft? I wanted in.&lt;/p&gt;

&lt;p&gt;I know some readers right now are probably saying, "oh they cheat, everyone cheats". Yeah, well, some might, but I'm always willing to give the benefit of a doubt. In my quest for answers, I've stumbled across many books, how-to's, and personalities with fancy cars and book collections.&lt;/p&gt;

&lt;p&gt;One common message stood out:&lt;/p&gt;

&lt;h3&gt;
  
  
  'Get what I need to know and get out'.
&lt;/h3&gt;

&lt;p&gt;I'm going to compare how I used to study and how I studied after learning this new technique.&lt;/p&gt;

&lt;p&gt;I'm assuming most textbooks are structured in this fashion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A chapter is ~35 pages&lt;/li&gt;
&lt;li&gt;Takes about two hours to "read" one chapter (longer with note-taking)&lt;/li&gt;
&lt;li&gt;Summary section at the end of the chapter (with review questions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Old Me Studying a Textbook Chapter&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Attempt to read the entire chapter from start to finish&lt;/li&gt;
&lt;li&gt;Take notes along the way&lt;/li&gt;
&lt;li&gt;If I haven't burned out, try to answer the review questions&lt;/li&gt;
&lt;li&gt;Return to class with little to no understanding of what I "studied"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;New Me Studying a Textbook Chapter&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jump straight to the end of the chapter&lt;/li&gt;
&lt;li&gt;Test my existing knowledge based on review questions&lt;/li&gt;
&lt;li&gt;Note the review questions I got incorrect&lt;/li&gt;
&lt;li&gt;Jump to each section of the chapter related to my incorrect answers&lt;/li&gt;
&lt;li&gt;Take notes on those sections&lt;/li&gt;
&lt;li&gt;Return to the summary and look for any gaps in my understanding&lt;/li&gt;
&lt;li&gt;Repeat the earlier steps if necessary&lt;/li&gt;
&lt;li&gt;Return to class and start a conversation on the chapter to confirm my knowledge&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I was able to shorten what used to take about two to five hours to roughly 40 minutes to an hour on average. I'm looking at a 90% reduction in time invested (at best) while increasing knowledge retention, and preventing burn-out. An all-around win-win.&lt;/p&gt;

&lt;p&gt;So, these top students were able to study for multiple courses in the same amount of time I barely studied one. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why did I take the chapter review before reading anything about the chapter?
&lt;/h2&gt;

&lt;p&gt;I needed to know what I need to know. I am literally wasting time reading about something that I already understood.&lt;/p&gt;

&lt;p&gt;So, if there is an assessment available, take it before diving in. I'm always surprised at what I may already know. Sometimes I get everything wrong. And that's perfectly fine. Now I know what I need to review. I never go in without a map of what I need to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know What to Know
&lt;/h2&gt;

&lt;p&gt;This is the key to fast learning. Who'll win a scavenger hunt first? The player with a map or the player without the map?&lt;/p&gt;

&lt;p&gt;Unfortunately, every article, book, or piece of learning material is not structured like a college text-book. So, how would I be able to apply this same practice?&lt;/p&gt;

&lt;p&gt;I learned of two basic writing principles which apply to just about every piece of non-fiction:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Thesis statements&lt;/li&gt;
&lt;li&gt;Supporting information&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The thesis statement is exactly what the author wants the reader to understand. Everything else is supporting information.&lt;/p&gt;

&lt;p&gt;Sometimes a thesis statement is a sentence. Maybe a paragraph. If we're lucky, the author will explicitly start off with a &lt;em&gt;summary&lt;/em&gt; of everything he or she will discuss.&lt;/p&gt;

&lt;p&gt;My thesis statement for this article is one sentence. It's bold and in large text. It's hard to miss. If it makes sense to the reader, they can stop there and continue with their day.&lt;/p&gt;

&lt;p&gt;Sometimes a book's title is the thesis statement. Maybe it's the title of the chapter. Sometimes the thesis statement tucked away midway through the opening paragraphs.&lt;/p&gt;

&lt;p&gt;If any part of the thesis statement is vague or does not make sense, make note of it and parse out the chapter or book for related information. Sometimes another book or article explains it better. Don't limit the learning process to the current document or book.&lt;/p&gt;

&lt;p&gt;The goal isn't to &lt;em&gt;read&lt;/em&gt; the book for prestige or achievement, but to actually gain practical knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However, the learning process is the same.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the thesis and try to explain it in my own words&lt;/li&gt;
&lt;li&gt;If I'm unable to, make note of what doesn't make sense&lt;/li&gt;
&lt;li&gt;Scan the book/chapter/article for what I need and note it&lt;/li&gt;
&lt;li&gt;Repeat if necessary&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If there's anything I've missed or other techniques you've acquired which works for you, let me know!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>career</category>
      <category>education</category>
      <category>school</category>
    </item>
  </channel>
</rss>
