<?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: Sanjar Afaq</title>
    <description>The latest articles on DEV Community by Sanjar Afaq (@sanjarcode).</description>
    <link>https://dev.to/sanjarcode</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%2F431500%2Fee1fe088-d109-4015-bffe-b46045c53633.jpeg</url>
      <title>DEV Community: Sanjar Afaq</title>
      <link>https://dev.to/sanjarcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanjarcode"/>
    <language>en</language>
    <item>
      <title>Keyboard input in Node.js</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Sat, 06 Jan 2024 08:19:52 +0000</pubDate>
      <link>https://dev.to/sanjarcode/keyboard-input-in-nodejs-2j93</link>
      <guid>https://dev.to/sanjarcode/keyboard-input-in-nodejs-2j93</guid>
      <description>&lt;p&gt;This article talks about working with keyboard input in Node.js. This code will run in the terminal.&lt;/p&gt;

&lt;p&gt;We'll be discussing the default way in Node to do this. Practically, people prefer using a library like &lt;a href="https://github.com/SBoudrias/Inquirer.js#readme"&gt;inquirer&lt;/a&gt; to create interactive CLIs.&lt;/p&gt;




&lt;p&gt;The &lt;a href="https://nodejs.org/api/readline.html"&gt;readline&lt;/a&gt; module can be used for reading input into programs.&lt;br&gt;
A promise version &lt;a href="https://nodejs.org/api/readline.html#promises-api"&gt;readline/promises&lt;/a&gt; is it's marked experimental. Works by default in v20.&lt;/p&gt;

&lt;p&gt;The APIs of the module allow for very granular control if needed - like position of cursor, row/column position, reading a line vs per character reads.&lt;/p&gt;

&lt;p&gt;I'll demonstrate two commonly needed interfaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read a sentence (until user presses enter). Like C++'s cin.&lt;/li&gt;
&lt;li&gt;Read single character&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. Read sentence (until 'Enter' is pressed)
&lt;/h2&gt;

&lt;p&gt;Since we get back something once, I'm using async-await.&lt;/p&gt;

&lt;p&gt;Logic (snippet)&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;readline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readline/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Take sentence input, until you press 'Enter'
 * Like C++ cin
 *
 * @param {String} message
 * @returns {String}
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&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;message&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;rl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createInterface&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&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;answer&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;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;question&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;rl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// stop listening&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;answer&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;A simple program&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;// copy code from above here&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;simpleSum&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter first number: &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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter second number: &lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sum is&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;simpleSum&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A more interesting program&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getGitHubName&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;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GitHub username: &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;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// yes, `fetch` is available by default in Node v20&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occurred&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;,&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;Code:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&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;Message:&lt;/span&gt;&lt;span class="dl"&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;await&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User found. Name:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;getGitHubName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Run code for single character
&lt;/h2&gt;

&lt;p&gt;More like run some code on keypress. This continuously listens for keypresses.&lt;br&gt;
Since each keypress runs some code, I'm using callback.&lt;/p&gt;

&lt;p&gt;Example: this is what Metro (React native dev process) runs like - when 'r' is pressed it reloads.&lt;/p&gt;

&lt;p&gt;Logic (snippet)&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;readline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readline/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * Continues listening for keypresses, and run code for each keypress
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listenKeyPresses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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="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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;key&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="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;rl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;readline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createInterface&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;rl&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="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;rl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;listenKeyPresses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&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="nf"&gt;listenKeyPresses&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;key&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="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;isLetter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&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="s2"&gt;`\b&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;isLetter&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;letter&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;Non-letter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;data&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="nx"&gt;listenKeyPresses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// run the example&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is very handy when testing, trying something new. Instead of creating a small frontend using HTML, CSS or JS, or setting up Postman. Just use this, setup key press and corresponding code run, and test quickly. Both input + output in the same terminal!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>core</category>
      <category>vanilla</category>
    </item>
    <item>
      <title>Detect file run as main or module</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Mon, 01 Jan 2024 07:52:03 +0000</pubDate>
      <link>https://dev.to/sanjarcode/detect-file-run-as-main-or-module-2fj2</link>
      <guid>https://dev.to/sanjarcode/detect-file-run-as-main-or-module-2fj2</guid>
      <description>&lt;p&gt;&lt;em&gt;There's a simple way in Python to know if current file is being run directly or as an import, using the &lt;code&gt;__main__&lt;/code&gt; variable. Any such way in Node.js?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yes, there is.&lt;/p&gt;

&lt;h2&gt;
  
  
  CommonJS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;module&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This file is being run directly.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This file is being imported as a module.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ESM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// mainModule.mjs&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;`file://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&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="s2"&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This ESM module is being run directly.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This ESM module is being imported as a module.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's the use of this?
&lt;/h2&gt;

&lt;p&gt;I write Node.js scripts for personal use, and it's good to have usage examples that console.log something. If a script is being run directly, it'll print the usage examples, otherwise it'll stay silent.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
    <item>
      <title>Node version enforcement and convenience</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Tue, 26 Dec 2023 19:48:29 +0000</pubDate>
      <link>https://dev.to/sanjarcode/node-version-enforcement-and-convenience-dfk</link>
      <guid>https://dev.to/sanjarcode/node-version-enforcement-and-convenience-dfk</guid>
      <description>&lt;h1&gt;
  
  
  Node versions
&lt;/h1&gt;

&lt;p&gt;Created Wed Dec 27, 2023 at 12:38 AM&lt;/p&gt;

&lt;p&gt;Many projects have bad documentation or ways around what Node.js version they use, and how to load it.&lt;br&gt;
But there's a simple explicit way to do both enforcement and convenience at once.&lt;/p&gt;

&lt;p&gt;It involves making changes to 4 files - &lt;code&gt;.nvmrc&lt;/code&gt;, &lt;code&gt;.npmrc&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt; and terminal hook (&lt;code&gt;.zshrc&lt;/code&gt; for example).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enforcement - the app will raise errors for wrong versions during &lt;code&gt;npm install&lt;/code&gt;. &lt;code&gt;.npmrc&lt;/code&gt; and &lt;code&gt;package.json&lt;/code&gt; do this, since any app is started by an npm script. This raises an error during &lt;code&gt;npm install&lt;/code&gt; itself for wrong Node version, which is a good thing. See &lt;a href="https://stackoverflow.com/a/61403989/11392807"&gt;StackOverflow&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;/.npmrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   engine-strict&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/package.json&lt;/code&gt;. See &lt;a href="https://docs.npmjs.com/cli/v10/configuring-npm/package-json#engines"&gt;engines property on npmjs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"engines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;=16"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;supports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;like&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&amp;gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;optionally,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;even&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`npm`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specified&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Convenience&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Manual load - Add &lt;code&gt;.nvmrc&lt;/code&gt; with the node version (by running &lt;code&gt;node -v &amp;gt; .nvmrc&lt;/code&gt;), then manually do &lt;code&gt;nvm use&lt;/code&gt; inside the directory. Don't have to remember "x" in &lt;code&gt;nvm use x&lt;/code&gt;, good.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;/.nvmrc&lt;/code&gt; and (for safety/other &lt;a href="https://stackoverflow.com/questions/27425852/what-uses-respects-the-node-version-file"&gt;environments&lt;/a&gt;) &lt;code&gt;/.node-version&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="mf"&gt;16.20&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



&lt;ol&gt;
&lt;li&gt;Auto load - remembering and doing &lt;code&gt;nvm use&lt;/code&gt; for each new terminal is lame. So, add &lt;code&gt;.nvmrc&lt;/code&gt; to the project as usual, and also add a function that loads the node version. Fully automatic. See &lt;a href="https://github.com/nvm-sh/nvm?tab=readme-ov-file#deeper-shell-integration"&gt;Deeper shell integration&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;~/.zshrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# for ZSH: Add to .zshrc https://github.com/nvm-sh/nvm?tab=readme-ov-file#zsh&lt;/span&gt;
  &lt;span class="c"&gt;# for bash: Add to .bashrc https://github.com/nvm-sh/nvm?tab=readme-ov-file#bash&lt;/span&gt;
  &lt;span class="c"&gt;# optionally can do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notes and gotchas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set global default: &lt;code&gt;nvm&lt;/code&gt; has a bad UI. To set global default, one has to run &lt;code&gt;nvm use alias default _version_&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use specific node version (temporarily - for terminal session) - &lt;code&gt;nvm use _version_&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;On mac, make sure to run &lt;code&gt;brew uninstall node&lt;/code&gt;. Homebrew node messes up with nvm global default - it just takes over the default.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  PS
&lt;/h2&gt;

&lt;p&gt;Time to take &lt;a href="https://asdf-vm.com/"&gt;asdf&lt;/a&gt; seriously?&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
    <item>
      <title>Hot reload setup for Obsidian plugin development</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Tue, 14 Nov 2023 15:27:07 +0000</pubDate>
      <link>https://dev.to/sanjarcode/hot-reload-setup-for-obsidian-plugin-development-29i1</link>
      <guid>https://dev.to/sanjarcode/hot-reload-setup-for-obsidian-plugin-development-29i1</guid>
      <description>&lt;p&gt;&lt;a href="https://obsidian.md/"&gt;Obsidian&lt;/a&gt; is a markdown based note taking tool. It has a rich plugin ecosystem. Most plugins are free and open-source.&lt;/p&gt;

&lt;p&gt;This article talks about general development setup of an Obsidian plugin. It's not focused on creating a new plugin from scratch, but for making changes to existing plugins - so you can fix bugs directly, make your life easier and help everyone at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vault setup
&lt;/h2&gt;

&lt;p&gt;By vault I mean an Obsidian notebook (folder).&lt;/p&gt;

&lt;p&gt;Step 1: Create a new Obsidian vault&lt;br&gt;
Step 2: Install and enable this &lt;a href="https://github.com/pjeby/hot-reload"&gt;hot-reload plugin&lt;/a&gt; as usual in this new vault.&lt;/p&gt;

&lt;p&gt;Note: you can install/develop a plugin in an existing vault too, assuming you have a safe backup of the vault.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the plugin code
&lt;/h2&gt;

&lt;p&gt;Example plugin - &lt;a href="https://github.com/JYC333/obsidian-attachment-name-formatting"&gt;https://github.com/JYC333/obsidian-attachment-name-formatting&lt;/a&gt;&lt;br&gt;
Step 1: Clone the plugin repo inside &lt;code&gt;.obsidian/plugins&lt;/code&gt;&lt;br&gt;
Step 2: Open the cloned folder in an editor.&lt;br&gt;
Step 3: Change the "name", "id" and "description" in the manifest to some recognizable name. I usually do this in a new git branch.&lt;br&gt;
Step 4: Install dependencies&lt;br&gt;
Step 5: Start the plugin development mode, and make sure that the built files are directly kept in the &lt;code&gt;.obsidian/plugins/cloned-plugin-name&lt;/code&gt; folder. You need to look make sure atleast &lt;code&gt;main.js&lt;/code&gt;, &lt;code&gt;manifest.json&lt;/code&gt; exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the plugin (from folder)
&lt;/h2&gt;

&lt;p&gt;In Obsidian (inside the vault), go to Settings &amp;gt; Community Plugins &amp;gt; Scroll down until you reach 'Installed Plugins' section.&lt;/p&gt;

&lt;p&gt;Press the refresh icon (beside folder) of the section. The "name" (as changed in manifest.json) should appear here. Enable the plugin. If it doesn't appear here, click the folder icon and see if the cloned folder is present or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing/observing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open the Obsidian developer tools panel. Top app panel &amp;gt; View &amp;gt; Toggle Developer tools.&lt;/li&gt;
&lt;li&gt;Start editing the app code, and changes will show up in Obsidian. Make sure the development server is running.&lt;/li&gt;
&lt;li&gt;Most development modes (React/Vue etc) will automatically re-build the code (produce main.js) on change of app code.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>notes</category>
      <category>obsidianmd</category>
      <category>javascript</category>
      <category>plugins</category>
    </item>
    <item>
      <title>CRA to Vite migration (JS, not TS), for beginners</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Sun, 24 Sep 2023 11:16:58 +0000</pubDate>
      <link>https://dev.to/sanjarcode/cra-to-vite-js-not-ts-for-beginners-3eaa</link>
      <guid>https://dev.to/sanjarcode/cra-to-vite-js-not-ts-for-beginners-3eaa</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/sanjar-notes/react/blob/954cee37d8a4537ed55ff42627afe1685f72d1f6/vault/1_React_info_and_setup/4_Migrating_to_Vite.md"&gt;GitHub link to article&lt;/a&gt;, &lt;a href="https://github.com/exemplar-codes/vite-react-js-template"&gt;vite-react-js-template&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Situation (ignorable)
&lt;/h2&gt;

&lt;p&gt;You have a React app, created using &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fcreate-react-app.dev%2F"&gt;create-react-app&lt;/a&gt; (CRA) project that you wish to migrate to &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fvitejs.dev%2Fguide%2F"&gt;Vite&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Why migrate (ignorable)
&lt;/h2&gt;

&lt;p&gt;CRA is really slow, especially the &lt;code&gt;npm install&lt;/code&gt; step.&lt;/p&gt;

&lt;p&gt;This usually results in failure during free deployments (like &lt;a href="https://www.render.com"&gt;render.com&lt;/a&gt;) - due to memory usage and timeouts.&lt;/p&gt;

&lt;p&gt;Moving to Vite.js solves this - npm install for projects is very fast, development experience is good and free deployments don't fail.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;You have your CRA project. Ok.&lt;/p&gt;

&lt;p&gt;We need to add Vite config files to this project. For this, create a new (blank) Vite project -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;npm create vite&lt;/code&gt; in the terminal.&lt;/li&gt;
&lt;li&gt;In the prompt - add project name ("hello-world"), select framework as &lt;code&gt;React&lt;/code&gt; and variant as &lt;code&gt;JavaScript + SWC&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; &lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rename component&lt;/strong&gt; &lt;code&gt;.js&lt;/code&gt; files to &lt;code&gt;.jsx&lt;/code&gt;. Util files don't need to be renamed. Just to be clear: a component file means any file having JSX code. &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fexemplar-codes%2Fposts-express-api-app%2Fcommit%2F52a0fe58befad2bda8eacf06383fa6f247fe04ef%3Fdiff%3Dsplit"&gt;See changes (view GitHub commit diff)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Move index.html and change shell files&lt;/strong&gt; - move index.html from &lt;code&gt;public&lt;/code&gt; to &lt;code&gt;src&lt;/code&gt; and change other "shell" files like App.js, index.js, App.css etc. &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fexemplar-codes%2Fposts-express-api-app%2Fcommit%2F45274accb63c538bb593354843c5c3c284a6b755%3Fdiff%3Dsplit"&gt;See changes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add vite.config.js, package.json&lt;/strong&gt;, package-lock.json - just copy this from the fresh vite project into your CRA project. Replace conflicting files. &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fexemplar-codes%2Fposts-express-api-app%2Fcommit%2F9134d111c7b5e54ddd2e58c434ec895333df3f82%3Fdiff%3Dsplit"&gt;See changes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle environment variables (optional&lt;/strong&gt; - if your project uses them) - code &lt;code&gt;process.env.PORT&lt;/code&gt; becomes &lt;code&gt;import.meta.env.PORT&lt;/code&gt;. Make similar changes at other places. &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fexemplar-codes%2Fposts-express-api-app%2Fcommit%2Fabd00a755defcc39020494610231ae6d734dfb52"&gt;See changes&lt;/a&gt;
Handle environment variables (optional - if your project uses them)&lt;/li&gt;
&lt;li&gt;Run the app - &lt;code&gt;npm run dev&lt;/code&gt; should work now.&lt;/li&gt;
&lt;li&gt;Cleanup - delete extra files if any.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment build folder (optional)&lt;/strong&gt; - Vite's build folder is named &lt;code&gt;dist&lt;/code&gt; (as opposed to CRA's &lt;code&gt;build&lt;/code&gt;). Change  corresponding backend code if needed. &lt;a href="https://github.com/exemplar-codes/posts-express-api-app/commit/3ea3ae51e9f4e343226f8eec788501533777ba46"&gt;See changes&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more info, see the GitHub trail (commits) starting from &lt;a href="https://github.com/exemplar-codes/posts-express-api-app/commit/52a0fe58befad2bda8eacf06383fa6f247fe04ef"&gt;https://github.com/exemplar-codes/posts-express-api-app/commit/52a0fe58befad2bda8eacf06383fa6f247fe04ef&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  EOT
&lt;/h2&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>createreactapp</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Unawaited async middleware errors in Express v4</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Sun, 27 Aug 2023 19:39:06 +0000</pubDate>
      <link>https://dev.to/sanjarcode/catch-async-middleware-errors-in-express-v4-53f7</link>
      <guid>https://dev.to/sanjarcode/catch-async-middleware-errors-in-express-v4-53f7</guid>
      <description>&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;I am working on a plain JS Express.js app. It has middlewares, a few routers.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Situation - strange error
&lt;/h2&gt;

&lt;p&gt;I was getting an error from Mongoose package. The error would crash the app, in spite of having an error sink - which would never get triggered (unexpected).&lt;/p&gt;

&lt;p&gt;I am trying to use the &lt;code&gt;.save()&lt;/code&gt; mongoose function, an async function, without &lt;code&gt;await&lt;/code&gt;. But there's a reason I do this - I wish to send the response before the call succeeds.&lt;/p&gt;

&lt;p&gt;Exact problem (comparison):&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;// error&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/xyz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// some code here&lt;/span&gt;
    &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// this _will_ throw an error (expected, ok)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;catch &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="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;next&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Everything is fine.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// runs (unexpected)&lt;/span&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

&lt;span class="c1"&gt;// error middleware doesn't run (app crashes)&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="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/xyz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// some code here&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// this _will_ throw an error (expected, ok)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;catch &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="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;next&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Everything is fine.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// doesn't run now, as expected&lt;/span&gt;

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

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

&lt;span class="c1"&gt;// error middleware runs (app doesn't crash)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  Fix (here)
&lt;/h2&gt;

&lt;p&gt;I needed to add &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;Since I did not wait for &lt;code&gt;product.save()&lt;/code&gt; (which is async - so error is thrown after some time), to express, the error never occurred.&lt;/p&gt;

&lt;p&gt;So, it never ran the code inside &lt;code&gt;catch&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;And therefore, the error middleware never ran.&lt;/p&gt;

&lt;p&gt;But the &lt;code&gt;product.save()&lt;/code&gt; does throw an error, and it does bubble up at the runtime level (Node.js process instead of within Express), crashing the app.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Hack - catch error at a lower level (runtime instead of Express)
&lt;/h2&gt;

&lt;p&gt;The following is a native way to catch errors. Add the following as the first middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unhandledRejection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hack, Unhandled Rejection at: Promise &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; reason: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// application specific logging, throwing an error, or other logic 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;Source: &lt;a href="https://stackoverflow.com/a/30650609/11392807"&gt;https://stackoverflow.com/a/30650609/11392807&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crash is prevented - since this will catch the unhandled error, prevent bubbling to the runtime level, so the crash will be prevented.&lt;/li&gt;
&lt;li&gt;The error middleware is still not called.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why would you I use this? If the app is old, there may be a lot of such "non-awaited" middlewares.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Actual fixes
&lt;/h2&gt;

&lt;p&gt;Any of these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;await&lt;/code&gt; if possible.&lt;/li&gt;
&lt;li&gt;For non awaited parts, use &lt;code&gt;.then&lt;/code&gt; and call &lt;code&gt;next(e)&lt;/code&gt; from &lt;code&gt;.catch&lt;/code&gt;. Example: If the user doesn't care about the result immediately.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If async middlewares (Express.js) contain code that doesn't use await. &lt;br&gt;
Then execution of such code starts happening outside the middleware chain.&lt;br&gt;
This leads to problems like failed triggering of error middlewares, app crashes, and inability to send a response.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
      <category>backend</category>
    </item>
    <item>
      <title>Use positives for conditionals - if, ternary true case, boolean variables</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Thu, 24 Aug 2023 11:31:36 +0000</pubDate>
      <link>https://dev.to/sanjarcode/use-positives-for-conditionals-if-ternary-true-case-boolean-variables-7d0</link>
      <guid>https://dev.to/sanjarcode/use-positives-for-conditionals-if-ternary-true-case-boolean-variables-7d0</guid>
      <description>&lt;h2&gt;
  
  
  Prefer positive conditionals/checks
&lt;/h2&gt;

&lt;p&gt;In conditionals - like &lt;code&gt;if&lt;/code&gt;, ternary, boolean variables, prefer storing/checking positive conditions over equivalent negative ones.&lt;/p&gt;

&lt;p&gt;what is positive depends on the goal of the feature.&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;// example 1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasNoEnergy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;getStatus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// problem: negative stored in boolean&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;hasNoEnergy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;injectFuel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;changeOrbit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// example 2&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasEnergy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getStatus&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasEnergy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// problem: negative checked in if&lt;/span&gt;
  &lt;span class="nf"&gt;injectFuel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;changeOrbit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// these are complicated, need to be read deliberately&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="c1"&gt;// simple, better&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasEnergy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getStatus&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;hasEnergy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;changeOrbit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;injectFuel&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;



</description>
    </item>
    <item>
      <title>How Express.js detects if a middleware is an error or request one</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Tue, 22 Aug 2023 22:19:47 +0000</pubDate>
      <link>https://dev.to/sanjarcode/how-expressjs-detects-if-a-middleware-is-an-error-or-request-one-3fhn</link>
      <guid>https://dev.to/sanjarcode/how-expressjs-detects-if-a-middleware-is-an-error-or-request-one-3fhn</guid>
      <description>&lt;h2&gt;
  
  
  Situation
&lt;/h2&gt;

&lt;p&gt;Suppose we have this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// usual code - app.METHOD, app.use, routers etc&lt;/span&gt;

&lt;span class="c1"&gt;// below: wont' be treated as error middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt; 


&lt;span class="c1"&gt;// below: will be treated as an error middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  Question
&lt;/h2&gt;

&lt;p&gt;How does Express.js know which one is an error middleware, given both &lt;code&gt;app.use&lt;/code&gt; take a callback (function).&lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;p&gt;Well it's quite simple. &lt;em&gt;JS allows us to calculate the number of params in a function&lt;/em&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length"&gt;MDN&lt;/a&gt;). Syntax example:&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;mySumFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;mySumFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was surprising for me since I thought callback (or functions in general) are black-boxes, we could just call them, and that was it. But no.&lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence
&lt;/h2&gt;

&lt;p&gt;Coming back to the topic, Express internally does this &lt;code&gt;.length&lt;/code&gt; to decide if the middleware is a "request" or an "error" one.&lt;/p&gt;

&lt;p&gt;See (Express.js repo at GitHub): &lt;a href="https://github.com/expressjs/express/blob/3531987844e533742f1159b0c3f1e07fad2e4597/lib/router/layer.js#L89"&gt;https://github.com/expressjs/express/blob/3531987844e533742f1159b0c3f1e07fad2e4597/lib/router/layer.js#L89&lt;/a&gt;&lt;/p&gt;

</description>
      <category>express</category>
      <category>node</category>
      <category>backend</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>Conditional middlewares in Express.js</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Thu, 17 Aug 2023 21:32:21 +0000</pubDate>
      <link>https://dev.to/sanjarcode/conditional-middlewares-in-expressjs-19f2</link>
      <guid>https://dev.to/sanjarcode/conditional-middlewares-in-expressjs-19f2</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/sanjar-notes/nodejs/blob/925a86d740ed42ff378d4635561a8913238b8471/home/4_resource_itineraries/2_Node_js_complete_guide_academind/5_Express_js/64_Conditional_middlewares.md"&gt;Github link to article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Situation
&lt;/h2&gt;

&lt;p&gt;There is a backend app with many middlewares, including two named X and Y. The requirement is that only X runs or Y runs based on a condition.&lt;br&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;How do we handle this?&lt;br&gt;
There are a few cases here, with minor variations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Keep it linear - we add the middlewares one after the other. In the body of these middlewares we &lt;code&gt;return&lt;/code&gt; early if the condition is not matching.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If both are custom middlewares
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mwX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// do X mw logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mwY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// do Y mw logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;mwX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myY&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- If any of them is library generated. Or if you don't want to litter conditional code into middlewares.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```js
// of course, this can be done using array too
function xConditional(req, res, next) {
    if(condition)
        return X;
    return ((req, res, next) =&amp;gt; { return next(); });
}

function yConditional(req, res, next) {
    if(condition)
        return Y;
    return ((req, res, next) =&amp;gt; { return next(); });
}


app.use([xConditional, yConditional])
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Ternary - works only if the condition is static (i.e. not dependent on &lt;code&gt;req&lt;/code&gt; or &lt;code&gt;res&lt;/code&gt;), we can use the ternary operator. &lt;code&gt;app.use(condition ? X : Y);&lt;/code&gt;. X and Y could be custom or library generated doesn't matter. Code:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;staticCondition&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="nx"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prefer differentiation based on route, method and router before doing this. They are in-built control mechanisms which are intuitive and easy to use.&lt;/li&gt;
&lt;li&gt;Can be generalized to more than 2 middlewares too.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Direct wrapper  (special case) - if the middlewares are exclusively conditional. Code:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;wrapperMiddleware&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// based on req or res logic or otherwise&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;wrapperMiddleware&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>express</category>
      <category>node</category>
      <category>backend</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Chained middlewares in Express.js</title>
      <dc:creator>Sanjar Afaq</dc:creator>
      <pubDate>Thu, 17 Aug 2023 21:22:57 +0000</pubDate>
      <link>https://dev.to/sanjarcode/chained-middlewares-in-expressjs-51ia</link>
      <guid>https://dev.to/sanjarcode/chained-middlewares-in-expressjs-51ia</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/sanjar-notes/nodejs/blob/925a86d740ed42ff378d4635561a8913238b8471/home/4_resource_itineraries/2_Node_js_complete_guide_academind/5_Express_js/63_Chain_of_middlewares.md"&gt;GitHub link to the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Situation
&lt;/h2&gt;

&lt;p&gt;Suppose I need to run multiple middlewares for the exact same method, route, router or maybe with &lt;code&gt;.use()&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Let's try with the &lt;code&gt;.use()&lt;/code&gt; one, should be simple, I just write them one below the other. &lt;/p&gt;

&lt;p&gt;But what if the number of middlewares are not known, or I'm lazy. Can I use a for loop?&lt;br&gt;
No. Since all &lt;code&gt;.use(callback)&lt;/code&gt; are callbacks, we never run them until we get a request - so it's &lt;em&gt;not possible&lt;/em&gt; with a for loop.&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution - how
&lt;/h2&gt;

&lt;p&gt;Since looping is not possible.&lt;br&gt;
Express supports comma separated syntax or an array of middlewares passed to &lt;code&gt;.use&lt;/code&gt; (and other functions).&lt;br&gt;
The syntax is very flexible - everything is linearized.&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution - syntax
&lt;/h2&gt;

&lt;p&gt;Here's the syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// already familiar&lt;/span&gt;


&lt;span class="c1"&gt;// 1. Comma-separated works fine too (all will be run in order)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Array also works &lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// 3. can use both - it still works&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 4. btw, nested arrays work too, Express just flattens them&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;myMiddleware3&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="nx"&gt;myMiddleware4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with &lt;code&gt;.router()&lt;/code&gt;, &lt;code&gt;method('', )&lt;/code&gt; too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doubt (ignorable)
&lt;/h2&gt;

&lt;p&gt;Q: Could it work with this notation of comma, or array if we can write a wrapper with a loop?&lt;br&gt;
A: It would work, but not properly or for call cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For middleware that don't respond. 

&lt;ol&gt;
&lt;li&gt;It would &lt;em&gt;seem&lt;/em&gt; to work. Since each middleware in the loop would call &lt;code&gt;next()&lt;/code&gt;, but the first iteration would end the wrapper (which is a middleware itself). So the others in the loop would run (but not in the queue - they will run independently). &lt;strong&gt;Doesn't work&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;If they respond - &lt;strong&gt;won't work&lt;/strong&gt;, see why: 

&lt;ul&gt;
&lt;li&gt;If the first one is a non-responding middleware, point 1 happens (out of order exec) - not acceptable.&lt;/li&gt;
&lt;li&gt;If we ignore out of order/independent execution. Let's see what happens, the responding middleware runs... fine, no. When the next middleware (be it responding or non-responding), we would get headers set error - since it would reach the 404.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I know, we can update &lt;code&gt;res.locals&lt;/code&gt; and catch that in 404, but the out of exec order is till not solved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Construct of arrays/comma separated middleware is a REQUIRED feature.&lt;/p&gt;

&lt;p&gt;It makes it easy to develop Express apps.&lt;/p&gt;

</description>
      <category>express</category>
      <category>node</category>
      <category>backend</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
