<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Decipher Code]]></title><description><![CDATA[Decipher Code]]></description><link>https://blog.decipher.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1615303716780/7tRwGdN5w.jpeg</url><title>Decipher Code</title><link>https://blog.decipher.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 01:46:37 GMT</lastBuildDate><atom:link href="https://blog.decipher.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[5 Patterns to Write Better and Clean Code in Python]]></title><description><![CDATA[Writing better code is always a challenge in any programming language. Before wring good code, you should have a better understanding of the programing language. Reading an entire book is time-consuming. At the same time, It will be hard to remember ...]]></description><link>https://blog.decipher.dev/5-patterns-to-write-better-and-clean-code-in-python</link><guid isPermaLink="true">https://blog.decipher.dev/5-patterns-to-write-better-and-clean-code-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[coding]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 29 Mar 2022 02:00:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1642788178212/cYB9qopr5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Writing better code is always a challenge in any programming language. Before wring good code, you should have a better understanding of the programing language. Reading an entire book is time-consuming. At the same time, It will be hard to remember patterns. <em>In this article, I will highlight a few tips and patterns to write better code in Python.</em> I am still new to Python, So it may be the case my code will be not as performant as code from an experienced developer.
You may be preparing for coding challenges for companies like Google, Facebook. To successfully pass such coding challenges, you have to solve lots of coding problems in Leetcode. In coding challenges, you have to solve multiple questions. Like Facebook ask you to solve 2 questions within 40mins. A Programing Language is not restricted to the coding challenge. You can pick any programming language to solve the problem. Whatever programming language you choose, you need some tricks and tweaks to solve problems in a limited time. This article will also help you in solving complex problems on <a target="_blank" href="https://leetcode.com/">Leetcode</a>.</p>
<p><img src="https://miro.medium.com/max/1400/0*oLZpSsSq-UQYtC-S" alt /></p>
<h2 id="heading-1-looping-with-index">1. Looping with Index</h2>
<p>While working on problems like <a target="_blank" href="https://leetcode.com/problems/two-sum/">Two Sum</a>, You need to iterate the list and get the index of items. You can get the index either using a counter or you can use <a target="_blank" href="https://docs.python.org/3.3/library/stdtypes.html?highlight=range#range">range</a> iterator to loop through the length of the list. You can also use <a target="_blank" href="https://docs.python.org/3.3/library/functions.html#enumerate">enumerate</a> to iterate an iterable object with an index.</p>
<p><strong>Using range operator:</strong></p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">twoSum</span>(<span class="hljs-params">nums, target</span>):</span>
    num_map = {}
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(nums)):
        <span class="hljs-keyword">if</span> nums[i] <span class="hljs-keyword">in</span> num_map:
            <span class="hljs-keyword">return</span> [num_map[nums[i]], i]
        <span class="hljs-keyword">else</span>:
            num_map[target-nums[i]] = i
print(twoSum([<span class="hljs-number">2</span>, <span class="hljs-number">7</span>, <span class="hljs-number">11</span>, <span class="hljs-number">15</span>], <span class="hljs-number">9</span>))
</code></pre>
<p><strong>Using enumerate:</strong></p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">twoSum</span>(<span class="hljs-params">nums, target</span>):</span>
    num_map = {}
    <span class="hljs-keyword">for</span> index, num <span class="hljs-keyword">in</span> enumerate(nums):
        <span class="hljs-keyword">if</span> num <span class="hljs-keyword">in</span> num_map:
            <span class="hljs-keyword">return</span> [num_map[num], index]
        <span class="hljs-keyword">else</span>:
            num_map[target-num] = index
</code></pre>
<h2 id="heading-2-slicing-of-iterable">2. Slicing of Iterable</h2>
<p>An iterable object can be iterated over using a loop. <a target="_blank" href="https://docs.python.org/3.3/library/functions.html?highlight=slice#slice">slice</a> function returns a slice object, that can extract a sublist from an iterable object. Since a <strong>string</strong> is also an iterable object. Slicing can also be used on strings. The syntax of the slice is <code>slice(_start_, _stop_[, _step_]).</code></p>
<pre><code class="lang-py">nums = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]
name = <span class="hljs-string">"123456"</span>
sslice = slice(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>, <span class="hljs-number">2</span>)
print(nums[slice(<span class="hljs-number">1</span>, <span class="hljs-number">6</span>)]) <span class="hljs-comment"># [1, 2, 3, 4, 5, 6]</span>
print(nums[sslice]) <span class="hljs-comment"># [2, 4, 6]</span>
print(name[sslice]) <span class="hljs-comment"># 246</span>
`
</code></pre>
<p>The above code can be simplified using square brackets. You can access <code>sublist</code> using square brackets.</p>
<p>Here start, stop and steps all are optional. The default value of <em>start</em>, <em>stop</em> and <em>steps</em> are 0, length of an object and 1 respectively.<br />You can also use negative values to change the flow. To understand the negative values, Let’s take an example <a target="_blank" href="https://leetcode.com/problems/palindrome-number/">palindrome-number</a> problem. There are multiple ways to solve this problem. The quick way to solve it is, Convert an integer into a string and reverse the string and compare.</p>
<pre><code class="lang-py"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">isPalindrome</span>(<span class="hljs-params">self, x</span>):</span>
        num1 = str(x)
        num2 = num1[::<span class="hljs-number">-1</span>]
        <span class="hljs-keyword">return</span> num1 == num2
print(Solution().isPalindromewithReverse(<span class="hljs-number">121</span>)) <span class="hljs-comment"># True</span>
print(Solution().isPalindromewithReverse(<span class="hljs-number">-121</span>)) <span class="hljs-comment"># False</span>
</code></pre>
<p>Here in the above example, The <strong><em>reverse</em></strong> of the string <strong>num1</strong> is assigned to <strong>num2</strong>.</p>
<img src="https://miro.medium.com/max/1400/0*fU0zW8daZLRrfwtA" alt />

Photo by <a target="_blank" href="https://unsplash.com/@brett_jordan?utm_source=medium&amp;utm_medium=referral">Brett Jordan</a> on <a target="_blank" href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a>



<h2 id="heading-3-memoization">3. Memoization</h2>
<p>There are cases, Where you need to write recursion code. Memoization can really improve the performance of the code. Memoization is also useful to solve Dynamic Programming coding problems. Memoize can be tricky to implement. However, Using the decorator function it is too easy to implement memoize code. If you want to know more about decorators, You can read my article <a target="_blank" href="/validations-in-python-using-metaprogramming-and-decorators-advanced-python-ee4d4278a6b3">Validation in Python using Decorator.</a><br />To explain this topic, We will solve <a target="_blank" href="https://leetcode.com/problems/powx-n">powx-n</a> problem from Leetcode. In this problem, We have to implement a function that calculates <code>x</code> raised to the power <code>n</code>.</p>
<p><strong>Code of Memoize Decorator:</strong></p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">join</span>(<span class="hljs-params">*args</span>):</span>
    <span class="hljs-keyword">return</span> reduce(<span class="hljs-keyword">lambda</span> a, b: <span class="hljs-string">f"<span class="hljs-subst">{a}</span>_<span class="hljs-subst">{b}</span>"</span>, args)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">memoize</span>(<span class="hljs-params">func</span>):</span>
    memo = {}
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">helper</span>(<span class="hljs-params">*args</span>):</span>
        key = join(*args)
        <span class="hljs-keyword">if</span> key <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> memo:
            memo[key] = func(*args)
        <span class="hljs-keyword">return</span> memo[key]
    <span class="hljs-keyword">return</span> helper
</code></pre>
<p>Now actual solution can be written as below</p>
<pre><code class="lang-py"><span class="hljs-meta">@memoize</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">powHelper</span>(<span class="hljs-params">x, n</span>):</span>
    <span class="hljs-keyword">if</span> n == <span class="hljs-number">0</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
    <span class="hljs-keyword">return</span> powHelper(x*x, n/<span class="hljs-number">2</span>) <span class="hljs-keyword">if</span> n % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> x * powHelper(x*x, (n<span class="hljs-number">-1</span>)/<span class="hljs-number">2</span>)
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">myPow</span>(<span class="hljs-params">self, x, n</span>):</span>
        m = n
        <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">0</span>:
            m *= <span class="hljs-number">-1</span>
        res = powHelper(x, m)
        <span class="hljs-keyword">return</span> res <span class="hljs-keyword">if</span> n &gt;= <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> <span class="hljs-number">1</span>/res
print(Solution().myPow(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>))  <span class="hljs-comment"># 8</span>
print(Solution().myPow(<span class="hljs-number">2</span>, <span class="hljs-number">5</span>))  <span class="hljs-comment"># 32</span>
print(Solution().myPow(<span class="hljs-number">2</span>, <span class="hljs-number">-5</span>))  <span class="hljs-comment"># 0.03125</span>
</code></pre>
<h2 id="heading-4-varargs-and-argument-unpacking">4. Varargs and Argument Unpacking</h2>
<p>To understand Varargs, Let’s take an example of a <strong>sum</strong> function. The sum is a function, which returns the summation of variable number parameters passed to the function.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sum</span>(<span class="hljs-params">*args</span>):</span>
    res = <span class="hljs-number">0</span>
    <span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> args:
        res += num
    <span class="hljs-keyword">return</span> res
print(sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)) <span class="hljs-comment"># 6</span>
print(sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)) <span class="hljs-comment"># 15</span>
</code></pre>
<p>Here <strong>sum</strong> function can accept variable arguments <strong>args</strong>. Since <strong>args is</strong> a tuple is an iterable object(tuple), We can also use <strong>reduce</strong> from functools. To learn more about functional programming, Read <a target="_blank" href="/functional-programming-in-python-easy-learning-b20207b2dd4e">Functional Programming in Python</a>.</p>
<pre><code class="lang-py"><span class="hljs-comment"># Using reduce, simplified version</span>
<span class="hljs-keyword">from</span> functools <span class="hljs-keyword">import</span> reduce
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sum</span>(<span class="hljs-params">*args</span>):</span>
    <span class="hljs-keyword">return</span> reduce(<span class="hljs-keyword">lambda</span> a, b: a+b, args)
print(sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>))
print(sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>))
</code></pre>
<p><strong>Note:</strong> In the above examples, <em>varargs</em> is a tuple. So we can unpack it.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">divide</span>(<span class="hljs-params">*args</span>):</span>
    num, den = args
    <span class="hljs-keyword">return</span> num/den
print(divide(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>))
</code></pre>
<p>You can also use <strong>named varargs. named varargs</strong> is a dictionary to accept multiple named arguments. <strong>Named</strong> <strong>varargs</strong> is very useful to take option dictionary.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">range</span>(<span class="hljs-params">**args</span>):</span>
    start = args[<span class="hljs-string">"start"</span>] <span class="hljs-keyword">if</span> <span class="hljs-string">"start"</span> <span class="hljs-keyword">in</span> args <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>
    end = args[<span class="hljs-string">"end"</span>] <span class="hljs-keyword">if</span> <span class="hljs-string">"end"</span> <span class="hljs-keyword">in</span> args <span class="hljs-keyword">else</span> <span class="hljs-number">100</span>
    res = []
    <span class="hljs-keyword">while</span> start &lt; end:
        res.append(start)
        start = start+<span class="hljs-number">1</span>
    <span class="hljs-keyword">return</span> res
print(range(start=<span class="hljs-number">10</span>, end=<span class="hljs-number">20</span>)) <span class="hljs-comment"># [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]</span>
</code></pre>
<img src="https://miro.medium.com/max/1400/0*8_hYONIoBdxe3SUL" alt />

Photo by <a target="_blank" href="https://unsplash.com/@tetrakiss?utm_source=medium&amp;utm_medium=referral">Arseny Togulev</a> on <a target="_blank" href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a>



<h2 id="heading-5-mapping-of-iterator">5. Mapping of Iterator</h2>
<p>Mapping of an iterable object is helpful to convert an iterable object. Mapping can be done using the <a target="_blank" href="programiz.com/python-programming/methods/built-in/map">map</a> function.</p>
<pre><code class="lang-py">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
result = map(<span class="hljs-keyword">lambda</span> x: x*x, numbers) <span class="hljs-comment"># return map object</span>
print(list(result)) <span class="hljs-comment"># need to convert to list</span>
<span class="hljs-comment"># Output: [1, 4, 9, 16, 25]</span>
</code></pre>
<p>The above example uses a <strong>lambda</strong> function. If the function has multiple lines of statements, You can use a custom function.</p>
<pre><code class="lang-py">numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">mapInt</span>(<span class="hljs-params">num</span>):</span>
    <span class="hljs-keyword">return</span> num*num <span class="hljs-keyword">if</span> num % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> num*num*num
print(list(map(mapInt, numbers)))
</code></pre>
<p>Mapping can be done on any iterable object including <a target="_blank" href="https://www.programiz.com/python-programming/set">sets</a>, <a target="_blank" href="https://www.programiz.com/python-programming/list">lists</a>, <a target="_blank" href="https://www.programiz.com/python-programming/tuple">tuples</a> etc.</p>
<p><strong>Note:</strong> There is a better way to map an iterable object. It is called <a target="_blank" href="https://www.programiz.com/python-programming/list-comprehension">List comprehensions</a>. List comprehension is a concise and elegant way to map an iterable object.</p>
<pre><code class="lang-py">Celsius = [<span class="hljs-number">39.2</span>, <span class="hljs-number">36.5</span>, <span class="hljs-number">37.3</span>, <span class="hljs-number">37.8</span>]
Fahrenheit = [((float(<span class="hljs-number">9</span>)/<span class="hljs-number">5</span>)*x + <span class="hljs-number">32</span>) <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> Celsius]
print(Fahrenheit) <span class="hljs-comment"># [102.56, 97.7, 99.14, 100.03999999999999]</span>
</code></pre>
<p>You can also map to a dictionary, set and tuple. To learn more read <a target="_blank" href="https://docs.python.org/3/tutorial/datastructures.html">datastructures</a></p>
<pre><code class="lang-bash">&gt;&gt;&gt; a = {x <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-string">'abracadabra'</span> <span class="hljs-keyword">if</span> x not <span class="hljs-keyword">in</span> <span class="hljs-string">'abc'</span>}
&gt;&gt;&gt; a
{<span class="hljs-string">'r'</span>, <span class="hljs-string">'d'</span>}
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, I have just mentioned a few tips and patterns. There are a lot of other cool concepts to be learned. To keep the article to a concise length, I have broken this article into multiple sub-article. I will publish those later. I have attached all reference link below.</p>
<h2 id="heading-references">References:</h2>
<ul>
<li><a target="_blank" href="https://docs.python.org/3/tutorial/datastructures.html">https://docs.python.org/3/tutorial/datastructures.html</a></li>
<li><a target="_blank" href="https://www.programiz.com/python-programming/list-comprehension">https://www.programiz.com/python-programming/list-comprehension</a></li>
<li><a target="_blank" href="https://www.programiz.com/python-programming">https://www.programiz.com/python-programming</a></li>
<li><a target="_blank" href="https://realpython.com/">https://realpython.com/</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Validation in Python using Metaprogramming and Decorator- Advanced Python]]></title><description><![CDATA[A Decorator is a special kind of declaration that can apply to a function to enhance its functionality. This is also called known as metaprogramming. Here we are trying to modify the functionality of a function on compile time. Metaprogramming is a c...]]></description><link>https://blog.decipher.dev/validation-in-python-using-metaprogramming-and-decorator-advanced-python</link><guid isPermaLink="true">https://blog.decipher.dev/validation-in-python-using-metaprogramming-and-decorator-advanced-python</guid><category><![CDATA[General Programming]]></category><category><![CDATA[Python]]></category><category><![CDATA[Validation]]></category><category><![CDATA[coding]]></category><category><![CDATA[advanced]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Sat, 01 Jan 2022 19:17:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1642788096920/C8pK3GR1f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A <strong>Decorator</strong> is a special kind of declaration that can apply to a function to <strong><em>enhance its functionality</em></strong><em>.</em> This is also called known as <strong>metaprogramming</strong>. Here we are trying to modify the functionality of a function on <em>compile time</em>. Metaprogramming is a cool concept in ant programing language. It can be used to apply certain checks before executing the actual function.<br />Let’s try to understand the use-case with an example.</p>
<p>Suppose we have a function <a target="_blank" href="https://en.wikipedia.org/wiki/Division_(mathematics">divide</a>), which accepts <em>numerators and denominators</em>. Here numerators and denominators should be real numbers. and denominators can’t be zero.<em>Let’s implement the function</em></p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_real_number</span>(<span class="hljs-params">num</span>):</span>
    <span class="hljs-keyword">return</span> type(num) == int <span class="hljs-keyword">or</span> type(num) == float


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">divide</span>(<span class="hljs-params">num, den</span>):</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span>(is_real_number(num) <span class="hljs-keyword">and</span> is_real_number(den)):
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid argument"</span>)
    <span class="hljs-keyword">if</span> den == <span class="hljs-number">0</span>:
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Number is not divisible by zero"</span>)
    <span class="hljs-keyword">return</span> num/den


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span>(<span class="hljs-params">*arg</span>):</span>
    <span class="hljs-keyword">if</span> any([<span class="hljs-keyword">not</span>(is_real_number(i)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> arg]):
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid argument"</span>)
    <span class="hljs-keyword">return</span> sum(arg)


print(divide(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>))  <span class="hljs-comment"># 5.0</span>
print(add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>))  <span class="hljs-comment"># 6</span>
print(divide(<span class="hljs-string">"10"</span>, <span class="hljs-number">2</span>))  <span class="hljs-comment"># ValueError: Invalid argument</span>
print(divide(<span class="hljs-number">10</span>, <span class="hljs-number">0</span>))  <span class="hljs-comment"># ValueError: Number is not divisible by zero</span>
</code></pre>
<p><strong>Explanation:</strong><br />If you look at the above example functions, We have added a few extra checks to verify passed arguments. These extra checks can be applied using metaprogramming without modifying the actual functions.</p>
<p><strong>You should know: </strong></p>
<p>Before proceeding further, There are a few concepts that you should know. These concepts will help to understand decorators.</p>
<ol>
<li>Everything is an object</li>
<li>Class is callable</li>
</ol>
<p><strong>Everything is an object</strong>: In python, everything is an object. Yes, class is also an object. A name can be bound to multiple variables including function. Check out the below example.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">greet</span>(<span class="hljs-params">name</span>):</span>
    print(<span class="hljs-string">f"Welcome Mr/Ms. <span class="hljs-subst">{name}</span>"</span>)


gr_8 = greet
greet(<span class="hljs-string">"Deepak"</span>)  <span class="hljs-comment"># Welcome Mr/Ms. Deepak</span>
gr_8(<span class="hljs-string">"Deepak"</span>)  <span class="hljs-comment"># Welcome Mr/Ms. Deepak</span>
</code></pre>
<p>We can also pass functions as arguments and use that functions.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">inc</span>(<span class="hljs-params">x</span>):</span>
    <span class="hljs-keyword">return</span> x + <span class="hljs-number">1</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">dec</span>(<span class="hljs-params">x</span>):</span>
    <span class="hljs-keyword">return</span> x - <span class="hljs-number">1</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">operate</span>(<span class="hljs-params">func, x</span>):</span>
    result = func(x)
    <span class="hljs-keyword">return</span> result


operate(inc, <span class="hljs-number">5</span>)  <span class="hljs-comment"># 6</span>
operate(dec, <span class="hljs-number">5</span>)  <span class="hljs-comment"># 4</span>
</code></pre>
<p>We can also return a function from a function.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span>():</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">inner</span>():</span>
        print(<span class="hljs-string">"Inner function"</span>)
    <span class="hljs-keyword">return</span> inner


outer = decorator()
outer()
<span class="hljs-comment"># Inner function</span>
</code></pre>
<p><strong>Class is callable:</strong> You can make a class callable object by adding <code>**def** **__call__**(self, *args, **kwargs)</code> function. A callable object is an object but can be called a function. When we execute or call the callable object, it will internally call the method <code>**__call__**</code></p>
<pre><code class="lang-py"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Callable</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"An instance of Callable was initialized"</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span>(<span class="hljs-params">self, *args, **kwargs</span>):</span>
        print(<span class="hljs-string">"Arguments are:"</span>, args, kwargs)


x = Callable()
print(<span class="hljs-string">"now calling the instance:"</span>)
x(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, x=<span class="hljs-number">11</span>, y=<span class="hljs-number">10</span>)
<span class="hljs-string">"""
An instance of Callable was initialized
now calling the instance:
Arguments are: (3, 4) {'x': 11, 'y': 10}
"""</span>
</code></pre>
<p>Now since we know the basic concepts, Let’s try to understand decorators.</p>
<h3 id="heading-decorators-using-function">Decorators using function</h3>
<p>A Decorator function is a single argument function. It takes a function as an argument and returns a helper function.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span>(<span class="hljs-params">func</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">inner</span>():</span>
        print(<span class="hljs-string">"run something before actual function"</span>)
        func()
        print(<span class="hljs-string">"run something after actual function"</span>)
    <span class="hljs-keyword">return</span> inner


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span>():</span>
    print(<span class="hljs-string">"something..."</span>)


decorated_func = decorator(func)
decorated_func()
<span class="hljs-string">"""
run something before actual function
something...
run something after actual function
"""</span>
</code></pre>
<p>As you can see in the above example, the <strong>decorator</strong> function takes <strong>func</strong> as function and add before/after statements. A <strong>decorator</strong> functionality can be implemented using <code>@decorator</code>expression.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decorator</span>(<span class="hljs-params">func</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">inner</span>():</span>
        print(<span class="hljs-string">"run something before actual function"</span>)
        func()
        print(<span class="hljs-string">"run something after actual function"</span>)
    <span class="hljs-keyword">return</span> inner


<span class="hljs-meta">@decorator</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span>():</span>
    print(<span class="hljs-string">"something..."</span>)


func()
<span class="hljs-string">"""
run something before actual function
something...
run something after actual function
"""</span>
</code></pre>
<p>You can also return a function that accepts <strong>varargs</strong> as an argument<strong>.</strong> This is very useful to override the function behaviour still gives full flexibility.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">prettify</span>(<span class="hljs-params">func</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">inner</span>(<span class="hljs-params">*args, **kwargs</span>):</span>
        print(<span class="hljs-string">"*"</span> * <span class="hljs-number">30</span>)
        func(*args, **kwargs)
        print(<span class="hljs-string">"*"</span> * <span class="hljs-number">30</span>)
    <span class="hljs-keyword">return</span> inner


<span class="hljs-meta">@prettify</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pretty_print</span>(<span class="hljs-params">*msg, **kwargs</span>):</span>
    print(*msg, **kwargs)


pretty_print(<span class="hljs-string">"Hello World"</span>)
pretty_print(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
<span class="hljs-string">"""
******************************
Hello World
******************************
******************************
1 2 3
******************************
"""</span>
</code></pre>
<h3 id="heading-decorators-using-class">Decorators using Class</h3>
<p>Just like function decorators, You can make callable object decorators. The biggest advantage of creating a class-based decorator is that it looks more declarative and clean compare to functional decorators.</p>
<p>To understand the concept, Let’s take our previous example of <strong>add</strong> and <strong>divide</strong> function. If you have noticed that both function as common validation of real numbers. We can create a common validator decorator class.</p>
<pre><code class="lang-py"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RealNumValidator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, func</span>):</span>
        self.func = func

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span>(<span class="hljs-params">self, *args, **kwds</span>):</span>
        <span class="hljs-keyword">if</span> any([<span class="hljs-keyword">not</span>(is_real_number(i)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> args]):
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid argument"</span>)
        <span class="hljs-keyword">return</span> self.func(*args)


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ZeroValidator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, func</span>):</span>
        self.func = func

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span>(<span class="hljs-params">self, *args, **kwds</span>):</span>
        <span class="hljs-keyword">if</span> len(args) &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">or</span> args[<span class="hljs-number">1</span>] == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Number is not divisible by zero"</span>)
        <span class="hljs-keyword">return</span> self.func(*args)
</code></pre>
<p>Now we have two argument validators. Let’s use this on real function.</p>
<pre><code class="lang-py"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RealNumValidator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, func</span>):</span>
        self.func = func

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span>(<span class="hljs-params">self, *args, **kwds</span>):</span>
        <span class="hljs-keyword">if</span> any([<span class="hljs-keyword">not</span>(is_real_number(i)) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> args]):
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid argument"</span>)
        <span class="hljs-keyword">return</span> self.func(*args)


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ZeroValidator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, func</span>):</span>
        self.func = func

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__call__</span>(<span class="hljs-params">self, *args, **kwds</span>):</span>
        <span class="hljs-keyword">if</span> len(args) &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">or</span> args[<span class="hljs-number">1</span>] == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Number is not divisible by zero"</span>)
        <span class="hljs-keyword">return</span> self.func(*args)


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_real_number</span>(<span class="hljs-params">num</span>):</span>
    <span class="hljs-keyword">return</span> type(num) == int <span class="hljs-keyword">or</span> type(num) == float


<span class="hljs-meta">@RealNumValidator</span>
<span class="hljs-meta">@ZeroValidator</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">divide</span>(<span class="hljs-params">num, den</span>):</span>
    <span class="hljs-keyword">return</span> num/den


<span class="hljs-meta">@RealNumValidator</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span>(<span class="hljs-params">*arg</span>):</span>
    <span class="hljs-keyword">return</span> sum(arg)


print(divide(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>))  <span class="hljs-comment"># 5.0</span>
print(add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>))  <span class="hljs-comment"># 6</span>
print(divide(<span class="hljs-string">"10"</span>, <span class="hljs-number">2</span>))  <span class="hljs-comment"># ValueError: Invalid argument</span>
print(divide(<span class="hljs-number">10</span>, <span class="hljs-number">0</span>))  <span class="hljs-comment"># ValueError: Number is not divisible by zero</span>
</code></pre>
<p>Now if you look at the functions, It looks much cleaner compare to its previous version.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>There are a lot of things to be covered in metaprogramming or decorators. I have just touched the surface of the water. Like I have given an example of <strong>chaining of decorators.</strong> This can be very useful to share reusable validations and apply them. Tracing of function calls, spying of function, Writing custom parsers etc. are very common use cases of metaprogramming. You can explore and let me know in the comment.</p>
<h3 id="heading-references">References:</h3>
<p><a target="_blank" href="https://python-course.eu/advanced-python/decorators-decoration.php">https://python-course.eu/advanced-python/decorators-decoration.php</a></p>
<p><strong>Originally Posted:</strong> <a target="_blank" href="https://levelup.gitconnected.com/validations-in-python-using-metaprogramming-and-decorators-advanced-python-ee4d4278a6b3">Validation in Python using Metaprogramming and Decorator- Advanced Python</a></p>
]]></content:encoded></item><item><title><![CDATA[Infinite scroll | Pagination on API using JavaScript Generators]]></title><description><![CDATA[While writing Frontend code, You may have a scenario where you have to fetch all records from an API using pagination. You can break the code into multiple functions to do so. However, Maintaining so many variables and passing states from one functio...]]></description><link>https://blog.decipher.dev/infinite-scroll-or-pagination-on-api-using-javascript-generators</link><guid isPermaLink="true">https://blog.decipher.dev/infinite-scroll-or-pagination-on-api-using-javascript-generators</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[asynchronous]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Sat, 02 Oct 2021 08:03:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1633077798704/yIRNlRhYE.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While writing Frontend code, You may have a scenario where you have to fetch all records from an API using pagination. You can break the code into multiple functions to do so. However, Maintaining so many variables and passing states from one function to another function, is not simple as it looks. The async nature of the data source makes it more complex. However, You can use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of">async-generator</a> functions to simplify it. In this article, I will explain how you can break this complex logic into simplified functions.</p>
<h2 id="1-create-a-mocked-data-lakesource">1. Create a mocked data lake/source</h2>
<p>To test out the functionality you required a data source. To mimic the real-api data source, I will create a list of dummy users.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> users = <span class="hljs-built_in">Array</span>(<span class="hljs-number">1000</span>)
  .fill()
  .map(<span class="hljs-function">(<span class="hljs-params">_, i</span>) =&gt;</span> ({ <span class="hljs-attr">name</span>: <span class="hljs-string">`user<span class="hljs-subst">${i}</span>`</span>, <span class="hljs-attr">id</span>: <span class="hljs-string">`id_<span class="hljs-subst">${i}</span>`</span> }));
<span class="hljs-keyword">const</span> TOTAL_RECORDS = users.length;

<span class="hljs-built_in">console</span>.log({<span class="hljs-attr">user</span>: users[<span class="hljs-number">0</span>], TOTAL_RECORDS});
<span class="hljs-comment">// { user: { name: 'user0', id: 'id_0' }, TOTAL_RECORDS: 1000 }</span>
</code></pre>
<h2 id="2-fetch-users-api-function">2. Fetch users API function</h2>
<p>You can use a promise-based API function to fetch records. However, I will use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">async-await</a> function to create this Fetch user API function</p>
<pre><code class="lang-js"><span class="hljs-comment">//service.js</span>

<span class="hljs-keyword">const</span> delay = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(r, <span class="hljs-number">1000</span>));

<span class="hljs-comment">/**
 * fetchUsers
 * 
 * @param {page, limit} current page number, limit of the records to fecth
 * @default {0, 100}
 * @returns 
 */</span>
<span class="hljs-keyword">const</span> fetchUsers = <span class="hljs-keyword">async</span> ({ page = <span class="hljs-number">0</span>, limit = <span class="hljs-number">100</span> }) =&gt; {
  <span class="hljs-keyword">const</span> start = page * limit; <span class="hljs-comment">// start index of the records</span>
  <span class="hljs-keyword">const</span> end = (page + <span class="hljs-number">1</span>) * limit; <span class="hljs-comment">// end index of the records</span>
  <span class="hljs-keyword">await</span> delay(); <span class="hljs-comment">// virtual delay of 1000ms</span>
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">data</span>: users.slice(start, end), <span class="hljs-comment">//Slice the records from start to end</span>
    <span class="hljs-attr">done</span>: end &gt;= TOTAL_RECORDS,
    start,
    end,
  };
};

<span class="hljs-comment">// [optional]</span>
<span class="hljs-comment">//export { fetchUsers };</span>
</code></pre>
<p>The above function <code>fetchUsers</code> takes options like <code>page</code> and <code>limit</code>. Page is defined as the current page of the pagination and limit is defined as the limit of records to be fetched. Delay is just and virtual delay of <em>1000ms</em> to mimic the actual network.</p>
<h2 id="3-fetch-all-records-using-generator-function">3. Fetch all records using Generator Function</h2>
<p>Traditionally, You can write a function using recursion to solve the problem. However, the Writing recursion version is too complex to understand. You can also use <em>for-loop/while-loop</em> using <em>async-await</em>.  Check out the below example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> records = [];
  <span class="hljs-keyword">let</span> options = { <span class="hljs-attr">page</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">limit</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">end</span>: <span class="hljs-number">100</span>, <span class="hljs-attr">total_records</span>: <span class="hljs-literal">Infinity</span> };

  <span class="hljs-keyword">while</span> (options.end &lt; options.total_records) {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetchUsers(options);
    records = records.concat(response.data);
    options.end = response.end;
    options.page = options.page + <span class="hljs-number">1</span>;
    options.total_records = response.total_records;
    <span class="hljs-built_in">console</span>.log(records[records.length - <span class="hljs-number">1</span>], response.start, response.end);
  }
}
<span class="hljs-comment">// { name: 'user199', id: 'id_199' } 100 200</span>
<span class="hljs-comment">// { name: 'user299', id: 'id_299' } 200 300</span>
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633076566299/lETPg5pUq.gif" alt="Oct-01-2021 16-17-16.gif" /></p>
<p>As you can see using a while-loop function, Your main function has to worry too much about other variables like <em>records</em>, <em>paging options</em>. In such scenarios, Generators shines well. Let's try to convert the above example into generators.</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 *
 * <span class="hljs-doctag">@param <span class="hljs-type">{page, limit}</span> </span>start page index, limit/chunk of the records to fecth on each call
 * <span class="hljs-doctag">@default <span class="hljs-type">{0, 100}</span></span>
 * <span class="hljs-doctag">@returns</span>
 */</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">fetchAllRecords</span>(<span class="hljs-params">{ page = <span class="hljs-number">0</span>, limit = <span class="hljs-number">100</span> } = {}</span>) </span>{
  <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-keyword">const</span> records = <span class="hljs-keyword">await</span> fetchUsers({ <span class="hljs-attr">page</span>: page++, limit });
    <span class="hljs-keyword">yield</span> records;
    <span class="hljs-keyword">if</span> (records.done) <span class="hljs-keyword">return</span>;
  }
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> api = fetchAllRecords();
  <span class="hljs-keyword">let</span> records = [];
  <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">let</span> record <span class="hljs-keyword">of</span> api) {
    records = records.concat(record.data);
        <span class="hljs-built_in">console</span>.log(records[record.end - <span class="hljs-number">1</span>], record.start, record.end);
  }
}
</code></pre>
<p><strong>Output:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1633076994439/ZYHvIY1tG.gif" alt="Oct-01-2021 16-29-18.gif" /></p>
<p>As you can see, Using generators makes code look much simpler and easy to read. </p>
<p><strong>Note:</strong> If you noticed line <code>for await (let record of api)</code>, Here in this line we are looking at the generator looping asynchronously. This <code>await</code> signals <code>for-loop</code> that <code>api</code> object is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator">async iterator</a> function to iterate. </p>
<h3 id="codesandbox">Codesandbox</h3>
<iframe src="https://codesandbox.io/embed/broken-lake-sjdw0?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>


<h2 id="conclusion">Conclusion:</h2>
<p>Async await does not make your API run faster. It just simplifies code and increases the readability of code. As someone wise once said.</p>
<blockquote>
<p>“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” — Martin Fowler</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[How to work with Date | JavaScript Weird Parts]]></title><description><![CDATA[Working with JavaScript has never been easy. You always required continuous learning and exploration of new APIs/specs. One of the toughest things is working with Date. You always struggle to find a suitable method or end up importing external librar...]]></description><link>https://blog.decipher.dev/how-to-work-with-date-or-javascript-weird-parts</link><guid isPermaLink="true">https://blog.decipher.dev/how-to-work-with-date-or-javascript-weird-parts</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[tips]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Mon, 23 Aug 2021 04:46:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1629645105951/KsmHnHPJN.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Working with JavaScript has never been easy. You always required continuous learning and exploration of new APIs/specs. One of the toughest things is working with <em>Date</em>. You always struggle to find a suitable method or end up importing external libraries like <a target="_blank" href="https://momentjs.com/">momentjs</a>. Here in this article, I will explain how you can create a simple utility library for all your needs by using plain JavaScript.</p>
<p><strong>Table of Contents:</strong></p>
<ul>
<li><a class="post-section-overview" href="#1-create-a-simple-exportable-module">1. Create a simple exportable module</a></li>
<li><a class="post-section-overview" href="#2-creating-a-date">2. Creating a Date</a><ul>
<li><a class="post-section-overview" href="#simple-hacks-to-date-constructor">Simple hacks to Date constructor</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#3-get-day-month-year">3. Get day, month, year</a><ul>
<li><a class="post-section-overview" href="#simple-hacks-to-date-getters">Simple hacks to Date getters</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#4-set-day-month-year">4. Set day, month, year</a><ul>
<li><a class="post-section-overview" href="#simple-hacks-working-with-monthaddsubtract">Simple hacks working with month(add/subtract)</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#5-format-a-date">5. Format a date</a><ul>
<li><a class="post-section-overview" href="#simple-custom-format-method">Simple custom format method</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#6-invalid-date">6. Invalid Date</a></li>
<li><a class="post-section-overview" href="#conclusion">Conclusion</a></li>
<li><a class="post-section-overview" href="#some-useful-hacks">Some useful hacks</a></li>
<li><a class="post-section-overview" href="#references">References</a></li>
</ul>
<h2 id="1-create-a-simple-exportable-module">1. Create a simple exportable module</h2>
<p>Before going further, Let's create an exportable module. Exporting methods can vary according to the framework used. Below, I have mention a few examples of how to export a method as a module.</p>
<p><strong>Nodejs:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>
<span class="hljs-built_in">exports</span>.isValid = <span class="hljs-function">(<span class="hljs-params">date</span>) =&gt;</span> {
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span></span>
};
</code></pre>
<p><strong>React with Webpack:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> isValid = <span class="hljs-function">(<span class="hljs-params">date</span>) =&gt;</span> {
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span></span>
};
</code></pre>
<p><strong>TypeScript:</strong></p>
<pre><code class="lang-ts"><span class="hljs-comment">//date.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> isValid = <span class="hljs-function">(<span class="hljs-params">date: <span class="hljs-built_in">Date</span></span>) =&gt;</span> {
  <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span></span>
};
</code></pre>
<h2 id="2-creating-a-date">2. Creating a Date</h2>
<p><strong>Date</strong> class provide multiple ways to create an object. To get the current date object you can use <code>new Date()</code>, <strong>Date</strong> constructor without any parameter. The other way to create a Date object, use the number value in the constructor(new Date(num)). Here, <strong>num</strong> representing the number of milliseconds since January 1, 1970, 00:00:00.</p>
<p><strong>To get current Date:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * today: Get the current date
 */</span>
<span class="hljs-built_in">exports</span>.today = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();

<span class="hljs-comment">// main.js</span>
<span class="hljs-keyword">const</span> { today } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./date"</span>);
<span class="hljs-built_in">console</span>.log(today()); <span class="hljs-comment">// 2021-08-22T15:59:47.482Z</span>
</code></pre>
<p><strong>To get current timestamp in milliseconds:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// date.js</span>

<span class="hljs-comment">/**
 * now: Get the current timestamp
 */</span>
<span class="hljs-built_in">exports</span>.now = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">Date</span>.now();

<span class="hljs-comment">// main.js</span>

<span class="hljs-keyword">const</span> { today, now } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./date"</span>);
<span class="hljs-built_in">console</span>.log(now()); <span class="hljs-comment">// 1629647987489</span>
</code></pre>
<h3 id="simple-hacks-to-date-constructor">Simple hacks to Date constructor</h3>
<pre><code class="lang-js"><span class="hljs-comment">// date.js</span>

<span class="hljs-keyword">const</span> [HR, DAY, WEEK] = [
  <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>,
  <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span> * <span class="hljs-number">24</span>,
  <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span> * <span class="hljs-number">24</span> * <span class="hljs-number">7</span>,
];
<span class="hljs-built_in">exports</span>.hourBefore = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">this</span>.now() - HR);
<span class="hljs-built_in">exports</span>.dayBefore = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">this</span>.now() - DAY);
<span class="hljs-built_in">exports</span>.weekBefore = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">this</span>.now() - WEEK);

<span class="hljs-comment">//main.js</span>

<span class="hljs-built_in">console</span>.log(hourBefore()); <span class="hljs-comment">//2021-08-22T14:59:47.489Z</span>
<span class="hljs-built_in">console</span>.log(dayBefore()); <span class="hljs-comment">// 2021-08-21T15:59:47.489Z</span>
<span class="hljs-built_in">console</span>.log(weekBefore()); <span class="hljs-comment">// 2021-08-15T15:59:47.489Z</span>
</code></pre>
<p><strong>Note:</strong> Since a month can be 28,29,30 or 31 days base on the type of year. And same time timezone varies with a local date. So working with a date in the month is a little tricky. I have explained few hacks to work with months in the below setters examples.</p>
<h2 id="3-get-day-month-year">3. Get day, month, year</h2>
<p>Getting a day, month or year from a Date object is quite simple. There are a lot of getter methods within a date object.</p>
<p><strong>Sample:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> currentDate = today();
<span class="hljs-built_in">console</span>.log(currentDate.toISOString()); <span class="hljs-comment">// 2021-08-22T16:38:27.164Z</span>
<span class="hljs-built_in">console</span>.log(currentDate.getTime()); <span class="hljs-comment">// 1629650307164</span>
<span class="hljs-built_in">console</span>.log(currentDate.getDate()); <span class="hljs-comment">// 23</span>
<span class="hljs-built_in">console</span>.log(currentDate.getDay()); <span class="hljs-comment">// 1</span>
<span class="hljs-built_in">console</span>.log(currentDate.getMonth()); <span class="hljs-comment">// 7</span>
<span class="hljs-built_in">console</span>.log(currentDate.getFullYear()); <span class="hljs-comment">// 2021</span>
<span class="hljs-built_in">console</span>.log(currentDate.getHours()); <span class="hljs-comment">// 0</span>
<span class="hljs-built_in">console</span>.log(currentDate.getMinutes()); <span class="hljs-comment">// 38</span>
</code></pre>
<p><strong>Note:</strong> Few of the biggest confusions are <strong>getDay</strong> and <strong>getMonth</strong>. These both two starts with <strong>0</strong>. Meaning, month <em>Jan</em> and day <em>Sunday</em> represent as <em>0</em> in month and day respectively. This is very confusing for the first time. To work with month and day, You can create an enum/constant map.</p>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>

<span class="hljs-keyword">const</span> MONTHS = { <span class="hljs-number">0</span>: <span class="hljs-string">"January"</span>, <span class="hljs-number">1</span>: <span class="hljs-string">"February"</span>, <span class="hljs-number">2</span>: <span class="hljs-string">"March"</span>, <span class="hljs-number">7</span>: <span class="hljs-string">"August"</span> }; <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> complete</span>
<span class="hljs-built_in">exports</span>.monthInString = <span class="hljs-function">(<span class="hljs-params">date</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> MONTHS[date.getMonth()];
};

<span class="hljs-keyword">const</span> DAYS = { <span class="hljs-number">0</span>: <span class="hljs-string">"Sunday"</span>, <span class="hljs-number">1</span>: <span class="hljs-string">"Monday"</span>, <span class="hljs-number">2</span>: <span class="hljs-string">"Tuesday"</span>, <span class="hljs-number">3</span>: <span class="hljs-string">"Wednesday"</span> }; <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> complete</span>
<span class="hljs-built_in">exports</span>.dayOfWeek = <span class="hljs-function">(<span class="hljs-params">date</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> DAYS[date.getDay()];
};

<span class="hljs-comment">// main.js</span>

<span class="hljs-built_in">console</span>.log(monthInString(today())); <span class="hljs-comment">// August</span>

<span class="hljs-built_in">console</span>.log(dayOfWeek(today())); <span class="hljs-comment">// Monday</span>
</code></pre>
<h3 id="simple-hacks-to-date-getters">Simple hacks to Date getters</h3>
<p>With the new <code>Date.toLocaleString</code> method, Now it is very easy to get day/month as string. You can pass locale as <em>"en-US"</em> and other options to format date string.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Get Day of the Week</span>
<span class="hljs-built_in">console</span>.log(today(), today().toLocaleString(<span class="hljs-string">"en-US"</span>, { <span class="hljs-attr">weekday</span>: <span class="hljs-string">"long"</span> })); <span class="hljs-comment">// 021-08-22T16:58:30.238Z Monday</span>
<span class="hljs-comment">// Get month of the Year</span>
<span class="hljs-built_in">console</span>.log(today(), today().toLocaleString(<span class="hljs-string">"en-US"</span>, { <span class="hljs-attr">month</span>: <span class="hljs-string">"long"</span> })); <span class="hljs-comment">// 021-08-22T16:58:30.238Z August</span>
</code></pre>
<p>You can also collect all information at once using destructure array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [month, day, year, hr, min, sec, meridiem] = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(
  <span class="hljs-number">2021</span>,
  <span class="hljs-number">08</span>,
  <span class="hljs-number">22</span>,
  <span class="hljs-number">18</span>,
  <span class="hljs-number">08</span>,
  <span class="hljs-number">08</span>
)
  .toLocaleString(<span class="hljs-string">"en-US"</span>)
  .split(<span class="hljs-regexp">/\W+/</span>); <span class="hljs-comment">//// 9/22/2021, 8:08:08 PM</span>
<span class="hljs-built_in">console</span>.log(month, day, year, hr, min, sec, meridiem); <span class="hljs-comment">// 9 22 2021 6 08 08 PM</span>
</code></pre>
<p>If you want to format or prefix a day/month/hr/min with zero, You can do so by passing the option "2-digit". You can also show the full name of a month.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [month, day, year, hr, min, sec] = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">22</span>, <span class="hljs-number">18</span>, <span class="hljs-number">08</span>, <span class="hljs-number">08</span>)
  .toLocaleString(<span class="hljs-string">"en-US"</span>, {
    <span class="hljs-attr">day</span>: <span class="hljs-string">"2-digit"</span>,
    <span class="hljs-attr">month</span>: <span class="hljs-string">"long"</span>,
    <span class="hljs-attr">year</span>: <span class="hljs-string">"2-digit"</span>,
    <span class="hljs-attr">hour</span>: <span class="hljs-string">"2-digit"</span>,
    <span class="hljs-attr">minute</span>: <span class="hljs-string">"2-digit"</span>,
    <span class="hljs-attr">second</span>: <span class="hljs-string">"2-digit"</span>,
    <span class="hljs-attr">hour12</span>: <span class="hljs-literal">false</span>,
  })
  .split(<span class="hljs-regexp">/\W+/</span>); <span class="hljs-comment">//// 9/22/2021, 8:08:08 PM</span>
<span class="hljs-built_in">console</span>.log(month, day, year, hr, min, sec); <span class="hljs-comment">// September 22 21 18 08 08</span>
</code></pre>
<p>_For more options, You can read <a target="_blank" href="https://www.w3schools.com/jsref/jsref_tolocalestring.asp">this</a> nice article._</p>
<h2 id="4-set-day-month-year">4. Set day, month, year</h2>
<p>Setting a day, month or year from a Date object is quite simple. Same as a getter, are a lot of setter methods available in a date object.</p>
<p><strong>List of setters:</strong> <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date</a></p>
<h3 id="simple-hacks-working-with-monthaddsubtract">Simple hacks working with month(add/subtract)</h3>
<pre><code class="lang-js"><span class="hljs-comment">// date.js</span>
<span class="hljs-comment">/**
 * addMonths: add a month to date
 * You can pass -(month) to subtract
 *
 * <span class="hljs-doctag">@param <span class="hljs-type">{Date}</span> <span class="hljs-variable">date</span></span>
 * <span class="hljs-doctag">@param <span class="hljs-type">{number}</span> <span class="hljs-variable">months</span></span>
 */</span>
<span class="hljs-built_in">exports</span>.addMonths = <span class="hljs-function">(<span class="hljs-params">date, months</span>) =&gt;</span> {
  <span class="hljs-keyword">var</span> d = date.getDate();
  date.setMonth(date.getMonth() + +months);
  <span class="hljs-keyword">if</span> (date.getDate() != d) {
    date.setDate(<span class="hljs-number">0</span>);
  }
  <span class="hljs-keyword">return</span> date;
};

<span class="hljs-built_in">exports</span>.subMonths = <span class="hljs-function">(<span class="hljs-params">date, months</span>) =&gt;</span> <span class="hljs-built_in">this</span>.addMonths(date, <span class="hljs-number">-1</span> * months);

<span class="hljs-comment">//main.js</span>

<span class="hljs-built_in">console</span>.log(today(), addMonths(today(), <span class="hljs-number">2</span>)); <span class="hljs-comment">//2021-08-22T16:30:11.826Z 2021-10-22T16:30:11.826Z</span>
<span class="hljs-built_in">console</span>.log(today(), subMonths(today(), <span class="hljs-number">2</span>)); <span class="hljs-comment">//2021-08-22T16:34:10.895Z 2021-06-22T16:34:10.895Z</span>
</code></pre>
<p>To learn more on adding/subtracting dates, Read below mention <strong>StackOverflow</strong> links.</p>
<ul>
<li><a target="_blank" href="https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date/36331522#36331522">https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date/36331522#36331522</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/5645058/how-to-add-months-to-a-date-in-javascript/13633692#13633692">https://stackoverflow.com/questions/5645058/how-to-add-months-to-a-date-in-javascript/13633692#13633692</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date">https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date</a></li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629660534629/5sSaai8WL.png" alt="1_1X-_xDbm03LntXVWYhKb7g.png" /></p>
<h2 id="5-format-a-date">5. Format a date</h2>
<p>There are multiple default standard format methods supported by the Date objects. You can use method likes <strong>toUTCString</strong>, <strong>toISOString</strong>, <strong>toLocaleString</strong> to get formatted string of date. However, there is no standard custom format method supported by the Date object. <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat#constructor">Intl</a> supports a lot of helper methods to work with date formatting.</p>
<p><strong>Note:</strong> <em>Intl</em> is not fully supported by all the browsers. You may have to polyfill methods based on need.</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-built_in">Date</span>.UTC(<span class="hljs-number">2012</span>, <span class="hljs-number">11</span>, <span class="hljs-number">20</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>));

<span class="hljs-comment">// US English uses month-day-year order</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">"en-US"</span>).format(date));
<span class="hljs-comment">// → "12/19/2012"</span>
<span class="hljs-comment">// British English uses day-month-year order</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">"en-GB"</span>).format(date));
<span class="hljs-comment">// → "19/12/2012"</span>

<span class="hljs-comment">// Chinese</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">"zh-TW"</span>).format(date));
<span class="hljs-comment">// → "2012/12/20"</span>
</code></pre>
<p>Same as <em>toLocaleString</em>, You can also pass options along with locale in <em>DateTimeFormat</em> constructor.</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> options = {
  <span class="hljs-attr">weekday</span>: <span class="hljs-string">"long"</span>,
  <span class="hljs-attr">year</span>: <span class="hljs-string">"numeric"</span>,
  <span class="hljs-attr">month</span>: <span class="hljs-string">"long"</span>,
  <span class="hljs-attr">day</span>: <span class="hljs-string">"numeric"</span>,
};
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(<span class="hljs-string">"de-DE"</span>, options).format(date));
<span class="hljs-comment">// → "Donnerstag, 20. Dezember 2012"</span>
</code></pre>
<p>Learn more on <em>DateTimeFormat</em>: <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat</a></p>
<h3 id="simple-custom-format-method">Simple custom format method</h3>
<p>Writing a format function is very complex. It evolves by parsing a date object, extract values and compact in a date string. As part of this article, we will not go in-depth. However based on the above useful utility methods, We can create a simple format function using replace command.</p>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>
<span class="hljs-built_in">exports</span>.formatString = <span class="hljs-function">(<span class="hljs-params">format, date</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [MM, DD, YYYY, hh, mm, ss, A] = date
    .toLocaleString(<span class="hljs-string">"en-US"</span>, {
      <span class="hljs-attr">day</span>: <span class="hljs-string">"2-digit"</span>,
      <span class="hljs-attr">month</span>: <span class="hljs-string">"2-digit"</span>,
      <span class="hljs-attr">year</span>: <span class="hljs-string">"numeric"</span>,
      <span class="hljs-attr">hour</span>: <span class="hljs-string">"2-digit"</span>,
      <span class="hljs-attr">minute</span>: <span class="hljs-string">"2-digit"</span>,
      <span class="hljs-attr">second</span>: <span class="hljs-string">"2-digit"</span>,
    })
    .split(<span class="hljs-regexp">/\W+/</span>);
  <span class="hljs-keyword">const</span> timeMap = { MM, DD, YYYY, hh, mm, ss, A };
  <span class="hljs-keyword">return</span> format.replace(<span class="hljs-regexp">/(\w+)/g</span>, <span class="hljs-function">(<span class="hljs-params">key</span>) =&gt;</span> timeMap[key]);
};

<span class="hljs-comment">// main.js</span>
<span class="hljs-keyword">var</span> date = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2012</span>, <span class="hljs-number">11</span>, <span class="hljs-number">20</span>, <span class="hljs-number">3</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
<span class="hljs-built_in">console</span>.log(formatString(<span class="hljs-string">"DD-MM-YYYY hh:mm:ss A"</span>, date)); <span class="hljs-comment">// 20-12-2012 03:00:00 AM</span>
</code></pre>
<p><strong>Note:</strong> As mentioned above, This format method is not tested for production support. It is just to demonstrate how a simple format function can be written. You can think of more complex definitions to create a format function.</p>
<h2 id="6-invalid-date">6. Invalid Date</h2>
<p><strong>Invalid Date</strong> is a spatial date object. Whenever you create a Date object with an invalid date value. Instead of throwing an error, It creates an object with a special value <strong>Invalid Date</strong>. This special object is very confusing. This will not throw any error in most of the operations performed on it. which can cause a lot of production issues. To avoid such issues, You can create an <strong>isValid</strong> function.</p>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>
<span class="hljs-built_in">exports</span>.isValid = <span class="hljs-function">(<span class="hljs-params">date</span>) =&gt;</span> date.toString() !== <span class="hljs-string">"Invalid Date"</span>;

<span class="hljs-comment">//main.js</span>
<span class="hljs-built_in">console</span>.log(isValid(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">"2021-08-22T16:30:11.826Z"</span>))); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(isValid(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">"ff-08-22T16:30:11.826Z"</span>))); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>In javascript, there is a lot of flexibility. However, This flexibility creates a lot of confusion and chaos. If you know these hacks, It can significantly improve your productivity. And a good way to learn, try and test in your project. Write more code and review more.</p>
<p><em>If you are looking for more useful methods like these, Please checkout <a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/">30-seconds-of-typescript/</a></em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1629660620442/ctP6b1OBd.jpeg" alt="helpful-tips-picture-id933100878.jpeg" /></p>
<h2 id="some-useful-hacks">Some useful hacks</h2>
<ul>
<li>Get timestamp without <em>now/getTime</em> method</li>
</ul>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(+<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>());
<span class="hljs-comment">//same as</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime());
</code></pre>
<ul>
<li>Getter than and equals</li>
</ul>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>
<span class="hljs-keyword">const</span> isAfterDate = <span class="hljs-function">(<span class="hljs-params">dateA, dateB</span>) =&gt;</span> dateA &gt; dateB;
<span class="hljs-keyword">const</span> isBeforeDate = <span class="hljs-function">(<span class="hljs-params">dateA, dateB</span>) =&gt;</span> dateA &lt; dateB;

<span class="hljs-comment">//main.js</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">11</span>) &gt; <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">10</span>));
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">09</span>) &gt; <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">10</span>));
<span class="hljs-built_in">console</span>.log(
  <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">10</span>).toISOString() === <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">2021</span>, <span class="hljs-number">08</span>, <span class="hljs-number">10</span>).toISOString()
);
</code></pre>
<p><strong>Read more:</strong> <a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/docs/isSameDate">https://decipher.dev/30-seconds-of-typescript/docs/isSameDate</a></p>
<ul>
<li>Sort array by date</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> users = [
  { <span class="hljs-attr">name</span>: <span class="hljs-string">"1"</span>, <span class="hljs-attr">dob</span>: <span class="hljs-string">"1989/8/26"</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">"2"</span>, <span class="hljs-attr">dob</span>: <span class="hljs-string">"1989/8/23"</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">"3"</span>, <span class="hljs-attr">dob</span>: <span class="hljs-string">"1989/8/25"</span> },
];

<span class="hljs-keyword">const</span> sortedUsers = users.sort(
  <span class="hljs-function">(<span class="hljs-params">{ dob: dob1 }, { dob: dob2 }</span>) =&gt;</span>
    <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(dob1).getTime() - <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(dob2).getTime()
);
<span class="hljs-built_in">console</span>.log(sortedUsers);

<span class="hljs-comment">/**
[
  { name: '2', dob: '1989/8/23' },
  { name: '3', dob: '1989/8/25' },
  { name: '1', dob: '1989/8/26' }
]
**/</span>
</code></pre>
<ul>
<li>Humanize duration</li>
</ul>
<pre><code class="lang-js"><span class="hljs-comment">//date.js</span>

<span class="hljs-built_in">exports</span>.formatDuration = <span class="hljs-function">(<span class="hljs-params">ms</span>) =&gt;</span> {
  ms = <span class="hljs-built_in">Math</span>.abs(ms);
  <span class="hljs-keyword">const</span> time = {
    <span class="hljs-attr">day</span>: <span class="hljs-built_in">Math</span>.floor(ms / <span class="hljs-number">86400000</span>),
    <span class="hljs-attr">hour</span>: <span class="hljs-built_in">Math</span>.floor(ms / <span class="hljs-number">3600000</span>) % <span class="hljs-number">24</span>,
    <span class="hljs-attr">minute</span>: <span class="hljs-built_in">Math</span>.floor(ms / <span class="hljs-number">60000</span>) % <span class="hljs-number">60</span>,
    <span class="hljs-attr">second</span>: <span class="hljs-built_in">Math</span>.floor(ms / <span class="hljs-number">1000</span>) % <span class="hljs-number">60</span>,
    <span class="hljs-attr">millisecond</span>: <span class="hljs-built_in">Math</span>.floor(ms) % <span class="hljs-number">1000</span>,
  };
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.entries(time)
    .filter(<span class="hljs-function">(<span class="hljs-params">val</span>) =&gt;</span> val[<span class="hljs-number">1</span>] !== <span class="hljs-number">0</span>)
    .map(<span class="hljs-function">(<span class="hljs-params">[key, val]</span>) =&gt;</span> <span class="hljs-string">`<span class="hljs-subst">${val}</span> <span class="hljs-subst">${key}</span><span class="hljs-subst">${val !== <span class="hljs-number">1</span> ? <span class="hljs-string">"s"</span> : <span class="hljs-string">""</span>}</span>`</span>)
    .join(<span class="hljs-string">", "</span>);
};
<span class="hljs-comment">// main.js</span>

<span class="hljs-built_in">console</span>.log(formatDuration(<span class="hljs-number">34325055574</span>));
</code></pre>
<p><strong>Read more:</strong> <a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/docs/formatDuration">https://decipher.dev/30-seconds-of-typescript/docs/formatDuration</a></p>
<h2 id="references">References</h2>
<ul>
<li><a target="_blank" href="https://decipher.dev/30-seconds-of-typescript">https://decipher.dev/30-seconds-of-typescript</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/tagged/javascript+date">https://stackoverflow.com/questions/tagged/javascript+date</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date</a></li>
<li><a target="_blank" href="https://www.w3schools.com/jsref/jsref_obj_date.asp">https://www.w3schools.com/jsref/jsref_obj_date.asp</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Internationalization in Plain React.js]]></title><description><![CDATA[While working in any MNC, You have to support customers from all around the world. Your app must support multi-lingual features. And The user should be able to switch between languages. Most of the time you choose third-party libraries like i18next. ...]]></description><link>https://blog.decipher.dev/internationalization-in-plain-reactjs</link><guid isPermaLink="true">https://blog.decipher.dev/internationalization-in-plain-reactjs</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 27 Jul 2021 03:42:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1627397132250/JhfBDCXhx.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While working in any MNC, You have to support customers from all around the world. Your app must support multi-lingual features. And The user should be able to switch between languages. Most of the time you choose third-party libraries like <a target="_blank" href="https://www.i18next.com/">i18next</a>. However, It comes will its own challenges.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627322118647/e04bFE-Pg.jpeg" alt="Opinionated" /></p>
<p><em>In this article, I will focus on creating a simple and easy to use module for Internationalization that also uses very few lines of code. I will not compare why you should or should not use third-party libraries.</em></p>
<p>Before moving forward, Let's understand the requirement of the library.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627322020808/WjytUEwcP.jpeg" alt="Project Requirements" /></p>
<h2 id="project-requirements">Project Requirements</h2>
<ol>
<li>Users should be able to toggle between languages</li>
<li>Users should see different text when a user switches to another language.</li>
</ol>
<h3 id="non-functional-requirement">Non-Functional requirement</h3>
<ol>
<li>Assuming we are using React.js, Library should support the latest hook concept of React.js</li>
<li>The library should provide an option to update translations on runtime(fetch over the network)</li>
<li>The library should provide support for default messages, In case if requested the key/value is not present in the set of messages</li>
<li>The library should provide a method to update the default locale based on user preference</li>
<li>Developers should be able to get messages in any locale, even though the default local is different. This will help to get messages in different languages at the same time.</li>
</ol>
<p><strong>Sample App:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627322320670/4MEMpZcLi.gif" alt="Final App" /></p>
<h2 id="creating-a-react-app">Creating a react app</h2>
<p>Creating a react app is pretty much simple. You can use <code>create-react-app</code> to create react app. If you already have your own app. You can skip this step and move to the next step.</p>
<pre><code class="lang-bash">npx create-react-app my-multi-lingual-app --template typescript
</code></pre>
<p>Once App is created, You can remove existing code from <strong>App.tsx</strong>.</p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/App.tsx</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>;

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p><strong>Note:</strong> <em>For this article, We will write code using Typescript. I always recommend using TypeScript for custom build libraries. Not only it reduces the efforts of explaining huge codes but it also provides better support by complimenting the bad parts of JS. You can read this article to find more reasons why <a target="_blank" href="https://javascript.plainenglish.io/im-not-using-javascript-anymore-6851c707b3d1">I’m Not Using JavaScript Anymore</a>.</em></p>
<h2 id="creating-an-i18n-package">Creating an i18n Package</h2>
<p>For simplicity, let us create a directory inside the <code>src</code> directory. There are plenty of articles available online like <strong><a target="_blank" href="https://docs.npmjs.com/creating-node-js-modules">How to create node.js modules</a></strong>. You can follow any of them to create a separate package and publish your library if you wish to do so.</p>
<p><strong> Create a file Internationalization.tsx</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/Internationalization.tsx</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{}&gt; = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> {children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
};
</code></pre>
<p>Let's import this and create a basic Application structure with default English text.</p>
<h2 id="update-html-template-for-the-application">Update HTML template for the Application</h2>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>;
<span class="hljs-keyword">import</span> { I18nProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"./i18n/internationalization"</span>;

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Controller"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> onLangChange("en-US")}&gt;
            En
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          |<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> onLangChange("zh-CN")}&gt;
            中文
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Welcome, Hello in English<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is default message: Message not found!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h3 id="test-i18nprovider-class-with-default-messages">Test I18nProvider class with default messages</h3>
<p>For our <strong>Internationalization</strong> module, We will be using <a target="_blank" href="https://reactjs.org/docs/context.html">React Context API</a>. To avoid direct exposure to the provider class, We will wrap the provider using the HOC component. You can read in detail <a target="_blank" href="https://itnext.io/combining-hocs-with-the-new-reacts-context-api-9d3617dccf0b">here</a>, How to create a wrapper class for Provider.</p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/Internationalization.tsx</span>

interface MessagesProp {
  [key: string]: { [key: string]: string };
}

<span class="hljs-keyword">const</span> I18nContext = createContext&lt;{
  <span class="hljs-attr">messages</span>: MessagesProp;
}&gt;({
  <span class="hljs-attr">messages</span>: {},
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{}&gt; = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [messages, setMessages] = useState&lt;any&gt;({
    <span class="hljs-string">"en-US"</span>: { <span class="hljs-attr">hello</span>: <span class="hljs-string">"Hello in English"</span> },
  });
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">messages</span>,
      }}
    &gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nContext.Provider</span>&gt;</span></span>
  );
};
</code></pre>
<p>To access the value from the provider class, Let's create a custom hook.</p>
<pre><code class="lang-js"><span class="hljs-comment">/// rest of the code</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{}&gt; = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
  <span class="hljs-comment">/// rest of the code</span>
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useI18n = <span class="hljs-function">() =&gt;</span> useContext(I18nContext);
</code></pre>
<p><strong>Update the <em>App.tsx</em>, To get the hardcoded messages</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">/// import custom hook</span>
<span class="hljs-keyword">import</span> { I18nProvider, useI18n } <span class="hljs-keyword">from</span> <span class="hljs-string">"./i18n/internationalization"</span>;

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { messages } = useI18n();
  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
  };
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        {/* rest of the code */}
        {/* Direct access to message */}
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Welcome, {messages["en-US"].hello}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is default message: Message not found!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="fetch-messages-from-the-network">Fetch messages from the network</h2>
<p>Once you refresh, You can see the hardcoded messages. Let's fetch messages from the network and set them as messages in <strong>I18nProvider</strong>. To do so we need to create a public method to context provide.</p>
<pre><code class="lang-js">interface MessagesProp {
  [key: string]: { [key: string]: string };
}
<span class="hljs-keyword">const</span> I18nContext = createContext&lt;{
  <span class="hljs-attr">messages</span>: MessagesProp;
  setMessages: <span class="hljs-function">(<span class="hljs-params">messages: MessagesProp</span>) =&gt;</span> <span class="hljs-keyword">void</span>;
  locale: string;
  setLocale: <span class="hljs-function">(<span class="hljs-params">locale: string</span>) =&gt;</span> <span class="hljs-keyword">void</span>;
}&gt;({
  <span class="hljs-attr">messages</span>: {},
  <span class="hljs-attr">setMessages</span>: <span class="hljs-function">() =&gt;</span> {},
  <span class="hljs-attr">locale</span>: <span class="hljs-string">"en-US"</span>,
  <span class="hljs-attr">setLocale</span>: <span class="hljs-function">() =&gt;</span> {},
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{ defaultLocale?: string }&gt; = <span class="hljs-function">(<span class="hljs-params">{
  children,
  defaultLocale = <span class="hljs-string">"en-US"</span>,
}</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [messages, setMessages] = useState&lt;any&gt;({});
  <span class="hljs-keyword">const</span> [locale, setLocale] = useState(defaultLocale);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">messages</span>,
        <span class="hljs-attr">locale</span>,
        <span class="hljs-attr">setLocale</span>,
        <span class="hljs-attr">setMessages</span>,
      }}
    &gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nContext.Provider</span>&gt;</span></span>
  );
};
</code></pre>
<p>Similarly, we have to expose the method to <strong>set locale</strong>. Accessing all these methods inside <strong>App.tsx</strong> is pretty much simple. Let's update <strong>App.tsx</strong>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> { I18nProvider, useI18n } <span class="hljs-keyword">from</span> <span class="hljs-string">"./i18n/internationalization"</span>;

<span class="hljs-comment">// virtual delay</span>
<span class="hljs-keyword">const</span> delay = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(r, <span class="hljs-number">2000</span>));

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { messages, setMessages, setLocale, locale } = useI18n();

  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
  };
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">Promise</span>.all([
      fetch(<span class="hljs-string">"/i18n/en-US.json"</span>).then(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x.json()),
      fetch(<span class="hljs-string">"/i18n/zh-CN.json"</span>).then(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x.json()),
      delay(),
    ]).then(<span class="hljs-function">(<span class="hljs-params">[enUS, zhCN]</span>) =&gt;</span> {
      setMessages({ <span class="hljs-string">"en-US"</span>: enUS, <span class="hljs-string">"zh-CN"</span>: zhCN });
    });
  }, [setMessages]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>{/* rest of the code */}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h3 id="handle-network-delay">Handle network delay</h3>
<p><em>Even we fetch the message from the network and set it to messages, We will still see a broken page. This is because we try to access message in <code>&lt;p&gt;Welcome, {messages["en-US"].hello}&lt;/p&gt;</code> without error handling. Due to a delay in the network(async), You will see this broken page. To avoid such issues, Or handle them elegantly. We can add a <strong>boolean(loaded)</strong> in our <strong>I18nProvider</strong>.</em></p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/Internationalization.tsx</span>

<span class="hljs-keyword">import</span> React, { createContext, useContext, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> I18nContext = createContext&lt;{
  <span class="hljs-comment">//rest of the code</span>
  <span class="hljs-attr">setLocale</span>: <span class="hljs-function">(<span class="hljs-params">locale: string</span>) =&gt;</span> <span class="hljs-keyword">void</span>;
  loaded: boolean;
}&gt;({
  <span class="hljs-comment">//rest of the code</span>
  <span class="hljs-attr">loaded</span>: <span class="hljs-literal">false</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> isEmpty = <span class="hljs-function">(<span class="hljs-params">val: any</span>) =&gt;</span>
  val == <span class="hljs-literal">null</span> || !(<span class="hljs-built_in">Object</span>.keys(val) || val).length;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{ defaultLocale?: string }&gt; = <span class="hljs-function">(<span class="hljs-params">{
  children,
  defaultLocale = <span class="hljs-string">"en-US"</span>,
}</span>) =&gt;</span> {
  <span class="hljs-comment">//rest of the code</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">messages</span>,
        <span class="hljs-attr">locale</span>,
        <span class="hljs-attr">setLocale</span>,
        <span class="hljs-attr">setMessages</span>,
        <span class="hljs-attr">loaded:</span> !<span class="hljs-attr">isEmpty</span>(<span class="hljs-attr">messages</span>),
      }}
    &gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nContext.Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useI18n = <span class="hljs-function">() =&gt;</span> useContext(I18nContext);
</code></pre>
<p>Now update <strong>App.tsx</strong> to show loading messages after messages are fetched from the network.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { I18nProvider, useI18n } <span class="hljs-keyword">from</span> <span class="hljs-string">"./i18n/internationalization"</span>;

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { messages, setMessages, setLocale, locale, loaded } = useI18n();

  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
  };
  <span class="hljs-comment">///rest of the code</span>

  <span class="hljs-keyword">if</span> (!loaded)
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>{/* rest of the code */}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="toggle-between-languages">Toggle between languages</h2>
<p><strong>I18nProvider</strong> exposes <strong>setLocale</strong> method. Bypassing locale, We can get messages from <strong>I18nProvider</strong>. It will be much easier to handle messages in one language than having multiple languages. To get text from <strong>I18nProvider</strong> based on current locale, We can add <strong>translate</strong> a helper function/method.</p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/Internationalization.tsx</span>

<span class="hljs-keyword">import</span> React, { createContext, useContext, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> I18nContext = createContext&lt;{
  <span class="hljs-comment">//rest of the code</span>
  <span class="hljs-attr">loaded</span>: boolean;
  translate: <span class="hljs-function">(<span class="hljs-params">
    key: string,
    defaultMessage?: string,
    locale?: string
  </span>) =&gt;</span> string | <span class="hljs-literal">undefined</span>;
}&gt;({
  <span class="hljs-comment">//rest of the code</span>
  <span class="hljs-attr">loaded</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">translate</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">""</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> isEmpty = <span class="hljs-function">(<span class="hljs-params">val: any</span>) =&gt;</span>
  val == <span class="hljs-literal">null</span> || !(<span class="hljs-built_in">Object</span>.keys(val) || val).length;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{ defaultLocale?: string }&gt; = <span class="hljs-function">(<span class="hljs-params">{
  children,
  defaultLocale = <span class="hljs-string">"en-US"</span>,
}</span>) =&gt;</span> {
  <span class="hljs-comment">//rest of the code</span>

  <span class="hljs-keyword">const</span> message = messages[locale];
  <span class="hljs-keyword">const</span> translate = <span class="hljs-function">(<span class="hljs-params">key: string, defaultMessage?: string, locale?: string</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> (locale ? messages[locale][key] : message[key]) || defaultMessage;
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">messages</span>,
        <span class="hljs-attr">locale</span>,
        <span class="hljs-attr">setLocale</span>,
        <span class="hljs-attr">setMessages</span>,
        <span class="hljs-attr">loaded:</span> !<span class="hljs-attr">isEmpty</span>(<span class="hljs-attr">messages</span>),
        <span class="hljs-attr">translate</span>,
      }}
    &gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nContext.Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useI18n = <span class="hljs-function">() =&gt;</span> useContext(I18nContext);
</code></pre>
<p>Now getting locale text within the <strong>App.tsx</strong> will be much easier.</p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/App.tsx</span>

<span class="hljs-comment">//rest of the code</span>

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { setMessages, translate, loaded, setLocale } = useI18n();

  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
    setLocale(code);
  };
  <span class="hljs-comment">//rest of the code</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Controller"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> onLangChange("en-US")}&gt;
            En
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          |<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> onLangChange("zh-CN")}&gt;
            中文
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Welcome, {translate("hello")}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is default message: Message not found!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="final-code">Final code</h2>
<p>Final code for <code>src/i18n/App.tsx</code></p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/App.tsx</span>

<span class="hljs-keyword">import</span> { useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./styles.css"</span>;
<span class="hljs-keyword">import</span> { I18nProvider, useI18n } <span class="hljs-keyword">from</span> <span class="hljs-string">"./i18n/internationalization"</span>;

<span class="hljs-comment">// virtual delay</span>
<span class="hljs-keyword">const</span> delay = <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(r, <span class="hljs-number">2000</span>));

<span class="hljs-keyword">const</span> Home = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { setMessages, translate, loaded, locale, setLocale } = useI18n();

  <span class="hljs-keyword">const</span> onLangChange = <span class="hljs-function">(<span class="hljs-params">code: string</span>) =&gt;</span> {
    <span class="hljs-comment">// toggle Language here</span>
    setLocale(code);
  };
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">Promise</span>.all([
      fetch(<span class="hljs-string">"/i18n/en-US.json"</span>).then(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x.json()),
      fetch(<span class="hljs-string">"/i18n/zh-CN.json"</span>).then(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x.json()),
      delay(),
    ]).then(<span class="hljs-function">(<span class="hljs-params">[enUS, zhCN]</span>) =&gt;</span> {
      setMessages({ <span class="hljs-string">"en-US"</span>: enUS, <span class="hljs-string">"zh-CN"</span>: zhCN });
    });
  }, [setMessages]);
  <span class="hljs-keyword">if</span> (!loaded)
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App-header"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Controller"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setLocale("en-US")}&gt;
            En
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
          |<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Button CN"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setLocale("zh-CN")}&gt;
            中文
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">message</span> ${<span class="hljs-attr">locale</span> === <span class="hljs-string">"zh-CN"</span> &amp;&amp; "<span class="hljs-attr">CN</span>"}`}&gt;</span>
          Welcome, {translate("hello")}
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
          This is default message:
          {translate("no_message", "Message not found!")}
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Home</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nProvider</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Final code for <code>src/i18n/Internationalization.tsx</code></p>
<pre><code class="lang-js"><span class="hljs-comment">/// src/i18n/Internationalization.tsx</span>

<span class="hljs-keyword">import</span> React, { createContext, useContext, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

interface MessagesProp {
  [key: string]: { [key: string]: string };
}

<span class="hljs-keyword">const</span> I18nContext = createContext&lt;{
  <span class="hljs-attr">messages</span>: MessagesProp;
  setMessages: <span class="hljs-function">(<span class="hljs-params">messages: MessagesProp</span>) =&gt;</span> <span class="hljs-keyword">void</span>;
  locale: string;
  setLocale: <span class="hljs-function">(<span class="hljs-params">locale: string</span>) =&gt;</span> <span class="hljs-keyword">void</span>;
  loaded: boolean;
  translate: <span class="hljs-function">(<span class="hljs-params">
    key: string,
    defaultMessage?: string,
    locale?: string
  </span>) =&gt;</span> string | <span class="hljs-literal">undefined</span>;
}&gt;({
  <span class="hljs-attr">messages</span>: {},
  <span class="hljs-attr">setMessages</span>: <span class="hljs-function">() =&gt;</span> {},
  <span class="hljs-attr">locale</span>: <span class="hljs-string">"en-US"</span>,
  <span class="hljs-attr">setLocale</span>: <span class="hljs-function">() =&gt;</span> {},
  <span class="hljs-attr">loaded</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">translate</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">""</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> isEmpty = <span class="hljs-function">(<span class="hljs-params">val: any</span>) =&gt;</span>
  val == <span class="hljs-literal">null</span> || !(<span class="hljs-built_in">Object</span>.keys(val) || val).length;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> I18nProvider: React.FC&lt;{ defaultLocale?: string }&gt; = <span class="hljs-function">(<span class="hljs-params">{
  children,
  defaultLocale = <span class="hljs-string">"en-US"</span>,
}</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [messages, setMessages] = useState&lt;any&gt;({});
  <span class="hljs-keyword">const</span> [locale, setLocale] = useState(defaultLocale);

  <span class="hljs-keyword">const</span> message = messages[locale];
  <span class="hljs-keyword">const</span> translate = <span class="hljs-function">(<span class="hljs-params">key: string, defaultMessage?: string, locale?: string</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> (locale ? messages[locale][key] : message[key]) || defaultMessage;
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">I18nContext.Provider</span>
      <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">messages</span>,
        <span class="hljs-attr">locale</span>,
        <span class="hljs-attr">setLocale</span>,
        <span class="hljs-attr">setMessages</span>,
        <span class="hljs-attr">loaded:</span> !<span class="hljs-attr">isEmpty</span>(<span class="hljs-attr">messages</span>),
        <span class="hljs-attr">translate</span>,
      }}
    &gt;</span>
      {children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">I18nContext.Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useI18n = <span class="hljs-function">() =&gt;</span> useContext(I18nContext);
</code></pre>
<h2 id="demo-application">Demo Application</h2>
<iframe src="https://codesandbox.io/embed/react-internationalization-screr?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>

<p><strong>Source code:</strong>
You can find the source code in the same code-sandbox, <a target="_blank" href="https://codesandbox.io/s/react-internationalization-screr">react-internationalization-screr</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We can clearly see by adding a few lines of code. We can create a basic simple Internationalization library. However, If your application is very big and you do not want to maintain your own custom library. You should use third-parties libraries. You will get better support and standardization.</p>
<p><strong>Thanks, Hope you enjoy this article. It will give you a basic idea of how to use React.js context APIs. If you find this useful, Please share and react. If you have any queries and suggestions, kindly do write on comments.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Functional Programming In JavaScript/TypeScript for Beginners]]></title><description><![CDATA[TypeScript or say JavaScript, is not designed to be functional programming(FP). JavaScript is a prototype-based object-oriented language. Meaning, Everything in the language is wrapped in an object. When you create a variable or constant underline it...]]></description><link>https://blog.decipher.dev/functional-programming-in-javascript-typescript-for-beginners</link><guid isPermaLink="true">https://blog.decipher.dev/functional-programming-in-javascript-typescript-for-beginners</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[best practices]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[Beginner Developers]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 13 Apr 2021 06:21:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617985467408/YaaOVhhad.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>TypeScript or say JavaScript, is not designed to be <a target="_blank" href="https://en.wikipedia.org/wiki/Functional_programming">functional programming(FP)</a>. JavaScript is a <a target="_blank" href="https://en.wikipedia.org/wiki/Prototype-based_programming">prototype-based</a> object-oriented language. Meaning, Everything in the language is wrapped in an object. When you create a variable or constant underline it uses an object.
<strong>So the question, How does JavaScript support functional programming?</strong>
To answer the above question, There is <a target="_blank" href="https://stackoverflow.com/questions/50835572/">Sugar Syntax</a> and auto wrapping. These help developer to write functional way without worrying too much. Let's understand in thorough.</p>
<p><strong>Note:</strong> <em>All code example has written in TypeScript. You can use <a target="_blank" href="https://www.typescriptlang.org/play">TypeScript Playground</a> to convert TS to JS code.</em></p>
<h2 id="basic-principles">Basic Principles</h2>
<p>Before going further, You should know some of the basic principles as described below.</p>
<ol>
<li>Pure Function</li>
<li>Deterministic Function</li>
<li>Higher-order Function</li>
<li>Immutability</li>
<li>Currying or Partial Function</li>
<li>Function composition</li>
</ol>
<h3 id="1-pure-function">1. Pure Function</h3>
<p>Pure functions are deterministic function with no side-effect. Meaning, The out will be always the same for the same inputs. Same time, it will not consume any other global variables.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1618118833377/CziflhK26.png" alt="Pure Function" /></p>
<p><strong>Example of Pure Function:</strong></p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateInterest</span>(<span class="hljs-params">p: <span class="hljs-built_in">number</span>, t: <span class="hljs-built_in">number</span>, r: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">return</span> (p * t * r) / <span class="hljs-number">100</span>;
}

<span class="hljs-built_in">console</span>.log(calculateInterest(<span class="hljs-number">1000</span>, <span class="hljs-number">5</span>, <span class="hljs-number">5</span>));

<span class="hljs-comment">//250</span>
</code></pre>
<p>Here, No matter what for the same inputs, the output will be the same.</p>
<p>The advantage of having a pure function, It is easy to understand and test. However, It is very hard to build an entire Application just using Pure Function. We needed some deterministic function too.</p>
<p><strong>Note:</strong> <a target="_blank" href="https://reactjs.org/docs/react-api.html#reactpurecomponent">React.js Pure components</a> are deterministic in nature, but they are not a pure function. It has side-effects in it like React.createElement which create document elements.</p>
<h3 id="2-deterministic-function">2. Deterministic Function</h3>
<p>A Deterministic function is where the output of the function is always deterministic. It may have side-effect but still, the output should not change with time. The same input should result in the same output</p>
<p><strong>Simple Example:</strong></p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">trim</span>(<span class="hljs-params">str: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">return</span> str.replace(<span class="hljs-regexp">/^\s+|\s+$/g</span>, <span class="hljs-string">""</span>);
}

<span class="hljs-built_in">console</span>.log(trim(<span class="hljs-string">"    This text had extra spaces.. "</span>));

<span class="hljs-comment">// "This text had extra spaces.."</span>
</code></pre>
<p><strong>Another Example:</strong></p>
<p>A deterministic function can have a side-effect. Meaning, It can have access to global variables.</p>
<pre><code class="lang-ts"><span class="hljs-built_in">enum</span> GENDER {
  MR = <span class="hljs-string">"Mr."</span>,
  MS = <span class="hljs-string">"Miss."</span>,
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greeting</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, is: GENDER = GENDER.MR</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hello, <span class="hljs-subst">${is == GENDER.MR ? GENDER.MR : GENDER.MS}</span> <span class="hljs-subst">${name}</span>`</span>;
}

<span class="hljs-built_in">console</span>.log(greeting(<span class="hljs-string">"Deepak"</span>));

<span class="hljs-comment">// "Hello, Mr. Deepak"</span>
</code></pre>
<p><strong>Example of a Non-Deterministic Function:</strong></p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rand</span>(<span class="hljs-params">num = 4</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.random().toString(<span class="hljs-number">16</span>).substr(-num);
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">uuid</span>(<span class="hljs-params"></span>): <span class="hljs-title">string</span> </span>{
  <span class="hljs-keyword">return</span> [rand(<span class="hljs-number">8</span>), rand(<span class="hljs-number">4</span>), rand(<span class="hljs-number">4</span>), rand(<span class="hljs-number">4</span>), rand(<span class="hljs-number">12</span>)].join(<span class="hljs-string">"-"</span>);
}
<span class="hljs-built_in">console</span>.log(uuid());
</code></pre>
<p>In the above example, the method <code>rand</code> using <code>Math.random</code> to generate a random number. The output of this API will be non-deterministic.</p>
<p>The good thing about a deterministic function that it is very common in any language. It is easy to create and understand. However, having side-effect in it. Some time is hard to test.</p>
<h3 id="3-hof-higher-order-function">3. HOF- Higher-Order Function</h3>
<p>A HOF can take function|s as input and can return a function as output.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> groupBy = &lt;T = <span class="hljs-built_in">any</span>&gt;(fn: <span class="hljs-function">(<span class="hljs-params">item: T, i: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">any</span>, data: T[]) =&gt;
  data.map(fn).reduce(<span class="hljs-function">(<span class="hljs-params">acc, val, i</span>) =&gt;</span> {
    acc[val] = (acc[val] || []).concat(data[i]);
    <span class="hljs-keyword">return</span> acc;
  }, {});

<span class="hljs-keyword">const</span> { odds, evens } = groupBy(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> (item % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> ? <span class="hljs-string">"evens"</span> : <span class="hljs-string">"odds"</span>), [
  <span class="hljs-number">1</span>,
  <span class="hljs-number">2</span>,
  <span class="hljs-number">3</span>,
  <span class="hljs-number">4</span>,
  <span class="hljs-number">5</span>,
]);
<span class="hljs-built_in">console</span>.log(odds, evens);

<span class="hljs-comment">// [ 1, 3, 5 ] [ 2, 4 ]</span>
</code></pre>
<p><strong>Note:</strong> Here in the above example, <strong>groupBy</strong> is a function. You may have noticed that I have not used the keyword <code>function</code> to create a function. Since I am using lambda as a function and assign it to a variable. After ES6/ES2015, JavaScript introduced the concept of lambda along with many more new syntax. Mostly lot of them are sugar syntax around the real implementation. You can read more <a target="_blank" href="https://www.w3schools.com/js/js_es6.asp">here</a>.</p>
<p><strong>groupBy</strong> is a function that takes an input <code>fn</code> as a function and <code>data</code> as an array. After computation on all item in the array, it returns an object of key and values.</p>
<p><strong>Note:</strong> Just like HOF, <a target="_blank" href="https://reactjs.org/docs/higher-order-components.html">HOC in React</a> is a component that can take another component|s as input and can return another component.</p>
<h3 id="4-immutability">4. Immutability</h3>
<p>Immutability is a concept where once data/variable is created can't be changed over a period of time. The idea to avoid the data race in cross-sharing environments like async programming, side-effects.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1618118766817/pRmMlSxto.png" alt="immutable javascript" /></p>
<p>JavaScript does have some Immutability APIs. However, Those are not enough. Let's see some of the examples.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> PI = <span class="hljs-number">3.141592653589793</span>;

<span class="hljs-comment">// PI = 1</span>
<span class="hljs-comment">// Cannot assign to 'PI' because it is a constant.</span>

<span class="hljs-keyword">const</span> numbers = <span class="hljs-built_in">Object</span>.freeze([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]);

<span class="hljs-comment">// Just like normal array, you can map on values</span>
numbers.forEach(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(x));

<span class="hljs-comment">// numbers.push()</span>

<span class="hljs-comment">// Cannot add property 4, object is not extensible</span>
<span class="hljs-comment">// OR in TS, Property 'push' does not exist on type 'readonly number[]'</span>
</code></pre>
<p>Since JavaScript is a dynamic language. Meaning, data can be changed on runtime. This makes it tough to implement Immutability in JavaScript. Same time, not all member/object support immutability. You can use <a target="_blank" href="https://github.com/immutable-js/immutable-js">immutable-js</a>. However, I recommend making immutability a practice and not including another library.</p>
<h4 id="simple-way-to-achieve-immutability">Simple way to achieve Immutability</h4>
<p><strong>Array:</strong></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> numbers = <span class="hljs-built_in">Object</span>.freeze([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]);

<span class="hljs-comment">// Just like normal array, you can loop on values</span>
numbers.forEach(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(x));

<span class="hljs-comment">// Copy array and add new</span>

<span class="hljs-keyword">const</span> anotherNumbers = [...numbers].concat(<span class="hljs-number">5</span>);

<span class="hljs-comment">//[1,2,3,4,5]</span>
</code></pre>
<p><strong>Object:</strong></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> configs = {
  API_URL: <span class="hljs-string">"some random urls"</span>,
  TIMEOUT: <span class="hljs-number">30</span> * <span class="hljs-number">60</span> * <span class="hljs-number">10000</span>, <span class="hljs-comment">//in ms</span>
};

<span class="hljs-keyword">const</span> newConfigs = {
  ...configs,
  SERVER_TIMEOUT: <span class="hljs-number">100</span> * <span class="hljs-number">60</span> * <span class="hljs-number">10000</span>, <span class="hljs-comment">//in ms</span>
};
<span class="hljs-comment">// OR</span>

<span class="hljs-keyword">const</span> newConfigs2 = <span class="hljs-built_in">Object</span>.assign({}, newConfigs, {
  SERVER_TIMEOUT: <span class="hljs-number">100</span> * <span class="hljs-number">60</span> * <span class="hljs-number">10000</span>,
});
</code></pre>
<p><strong>Map:</strong></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> details = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>([
  [<span class="hljs-string">"name"</span>, <span class="hljs-string">"deepak"</span>],
  [<span class="hljs-string">"address"</span>, <span class="hljs-string">"some where in world"</span>],
]);

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> key <span class="hljs-keyword">of</span> details.keys()) {
  <span class="hljs-built_in">console</span>.log(key);
}
<span class="hljs-comment">//"name" "address"</span>

<span class="hljs-keyword">const</span> updatedDetails = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>([
  ...details.entries(),
  [<span class="hljs-string">"newAddress"</span>, <span class="hljs-string">"still some where in world"</span>],
]);
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> key <span class="hljs-keyword">of</span> updatedDetails.keys()) {
  <span class="hljs-built_in">console</span>.log(key);
}
<span class="hljs-comment">//"name" "address" "newAddress"</span>
</code></pre>
<h2 id="5-currying-or-partial-function">5. Currying or Partial Function</h2>
<p>Currying is a method or technique in FP, Where a function can be composed to take input partially. Meaning, If a function <code>sum</code> take input <code>a</code> and <code>b</code> as arguments. Currying that function can make <code>sum</code> function take one argument <code>a</code> and return another function. We can use that newly created function to do summation later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1618118504590/1HQVfhQic.png" alt="Currying or Partial Function" /></p>
<p><strong>Let's see from example:</strong></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> split = <span class="hljs-function">(<span class="hljs-params">token = /\s+/, str = <span class="hljs-string">""</span></span>) =&gt;</span> str.split(token);

<span class="hljs-keyword">const</span> splitByHash = <span class="hljs-function">(<span class="hljs-params">str: <span class="hljs-built_in">string</span></span>) =&gt;</span> split(<span class="hljs-regexp">/#/</span>, str);

<span class="hljs-built_in">console</span>.log(splitByHash(<span class="hljs-string">"This#is#awesome"</span>));

<span class="hljs-comment">// [ 'This', 'is', 'awesome' ]</span>
</code></pre>
<p>In the above example, the <code>split</code> function takes token and string data to split in. We have created a function <code>splitByHash</code> where the token is already defined. It just takes a string to split it. Here, <code>splitByHash</code> is a partial function.</p>
<p><strong>Note:</strong> Above example is a good demonstration for the partial function. However, creating a partial function like this is not scalable for more than 2/3 arguments. We can use some basic utility to create a partial function or curried function.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// Helper method, Curries a function.</span>
<span class="hljs-comment">// https://decipher.dev/30-seconds-of-typescript/docs/curry</span>

<span class="hljs-keyword">const</span> curry = (fn: <span class="hljs-built_in">Function</span>, arity = fn.length, ...args: <span class="hljs-built_in">any</span>[]): <span class="hljs-function"><span class="hljs-params">any</span> =&gt;</span>
  arity &lt;= args.length ? fn(...args) : curry.bind(<span class="hljs-literal">null</span>, fn, arity, ...args);

<span class="hljs-keyword">const</span> split = <span class="hljs-function">(<span class="hljs-params">token = /\s+/, str = <span class="hljs-string">""</span></span>) =&gt;</span> str.split(token);

<span class="hljs-keyword">const</span> splitByHash = curry(split, <span class="hljs-number">2</span>)(<span class="hljs-string">"#"</span>);

<span class="hljs-built_in">console</span>.log(splitByHash(<span class="hljs-string">"This#is#awesome"</span>));
<span class="hljs-comment">// [ 'This', 'is', 'awesome' ]</span>
</code></pre>
<h2 id="6-function-composition">6. Function composition</h2>
<p>Function composition is a mathematical concept where an operation takes two functions f and g and produces a function h such that h(x) = g(f(x)).
For simplicity, (g º f)(x) = g(f(x))</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1618118639595/jUOlqNeTh.svg+xml" alt="function-composition" /></p>
<p><strong>Let's see from example:</strong></p>
<pre><code class="lang-ts"><span class="hljs-comment">// Helper method, Performs right-to-left function composition.</span>
<span class="hljs-comment">// https://decipher.dev/30-seconds-of-typescript/docs/compose/</span>

<span class="hljs-keyword">const</span> compose = <span class="hljs-function">(<span class="hljs-params">...fns: <span class="hljs-built_in">Function</span>[]</span>) =&gt;</span>
  fns.reduce(<span class="hljs-function">(<span class="hljs-params">f, g</span>) =&gt;</span> (...args: <span class="hljs-built_in">any</span>[]) =&gt; f(...[g(...args)]));

<span class="hljs-keyword">const</span> add10 = <span class="hljs-function">(<span class="hljs-params">x: <span class="hljs-built_in">number</span></span>) =&gt;</span> x + <span class="hljs-number">10</span>;
<span class="hljs-keyword">const</span> multiply = <span class="hljs-function">(<span class="hljs-params">x: <span class="hljs-built_in">number</span>, y: <span class="hljs-built_in">number</span></span>) =&gt;</span> x * y;
<span class="hljs-keyword">const</span> multiplyAndAdd5 = compose(add10, multiply);
<span class="hljs-built_in">console</span>.log(multiplyAndAdd5(<span class="hljs-number">5</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// 20</span>
</code></pre>
<p>In this example, you can see, <code>multiplyAndAdd5</code> is composed right to left. It's first multiply 2 number(5x2 = 10). And takes it out and add 10.</p>
<p><strong>Let see another example:</strong> Get average age of active users</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> sum = <span class="hljs-function">(<span class="hljs-params">nums: <span class="hljs-built_in">number</span>[]</span>) =&gt;</span> nums.reduce(<span class="hljs-function">(<span class="hljs-params">s, i</span>) =&gt;</span> s + i, <span class="hljs-number">0</span>)
<span class="hljs-keyword">const</span> average = <span class="hljs-function">(<span class="hljs-params">nums: <span class="hljs-built_in">number</span>[]</span>) =&gt;</span> sum(nums) / nums.length


<span class="hljs-keyword">const</span> getActiveUserAges = <span class="hljs-function">(<span class="hljs-params">data: UserType[] = []</span>) =&gt;</span> data.filter(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span> user.active === <span class="hljs-literal">true</span>).map(<span class="hljs-function"><span class="hljs-params">u</span> =&gt;</span> u.age)


<span class="hljs-keyword">const</span> users = [
  {
    name: <span class="hljs-string">"deepak"</span>,
    age: <span class="hljs-number">31</span>,
    active: <span class="hljs-literal">true</span>
  },
  {
    name: <span class="hljs-string">"sandy"</span>,
    age: <span class="hljs-number">20</span>,
    active: <span class="hljs-literal">false</span>
  },
  {
    name: <span class="hljs-string">"unknown"</span>,
    age: <span class="hljs-number">35</span>,
    active: <span class="hljs-literal">true</span>
  }
]
<span class="hljs-keyword">type</span> UserType = <span class="hljs-keyword">typeof</span> users[<span class="hljs-number">0</span>]

<span class="hljs-keyword">const</span> activeUsers = getActiveUserAges(users)

<span class="hljs-keyword">const</span>  = sum(activeUsers)


<span class="hljs-built_in">console</span>.log(sumOfAges/ activeUsers.length)
</code></pre>
<p>In the above example to get the average age of the active user, We have to call multiple methods. This is good. But we can make this more declarative using compose. If we have to write something functionally. It will look like as below</p>
<pre><code class="lang-ts"><span class="hljs-comment">// helper method</span>

<span class="hljs-keyword">const</span> compose = <span class="hljs-function">(<span class="hljs-params">...fns: <span class="hljs-built_in">Function</span>[]</span>) =&gt;</span>
  fns.reduce(<span class="hljs-function">(<span class="hljs-params">f, g</span>) =&gt;</span> (...args: <span class="hljs-built_in">any</span>[]) =&gt; f(...[g(...args)]));

<span class="hljs-comment">// sum of ages</span>
<span class="hljs-keyword">const</span> getSumAges = compose(sum, getActiveUserAges);
<span class="hljs-built_in">console</span>.log(getSumAges(users));

<span class="hljs-comment">// average of ages</span>
<span class="hljs-keyword">const</span> getAverageOfAges = compose(average, getActiveUserAges);
<span class="hljs-built_in">console</span>.log(getAverageOfAges(users));
</code></pre>
<p>As you can see, adding compose make it easy to mixing function and create another function. That can be reused later.</p>
<h2 id="some-real-life-problems">Some Real-Life Problems</h2>
<p>Now since we know the basics of FP. Let's explore with example.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/todos/"</span>) <span class="hljs-comment">// fetch todos</span>
    .then(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> r.json()); <span class="hljs-comment">// then extract json</span>
  <span class="hljs-comment">// Response Todo[]</span>
  <span class="hljs-comment">// Todo {userId: number, id: number, title: string, completed: boolean}</span>
  <span class="hljs-keyword">const</span> todos = response; <span class="hljs-comment">// extract Todo values</span>
  <span class="hljs-built_in">console</span>.log(todos[<span class="hljs-number">0</span>]); <span class="hljs-comment">// [{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}, ...]</span>

  <span class="hljs-keyword">const</span> completedTodos = todos.filter(<span class="hljs-function">(<span class="hljs-params">todo</span>) =&gt;</span> todo.completed);

  <span class="hljs-keyword">const</span> usersIds = completedTodos.map(<span class="hljs-function">(<span class="hljs-params">todo</span>) =&gt;</span> todo.userId);

  <span class="hljs-keyword">const</span> getAllUserById = <span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span>
    fetch(<span class="hljs-string">`https://jsonplaceholder.typicode.com/users/<span class="hljs-subst">${id}</span>`</span>).then(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span>
      r.json()
    );

  <span class="hljs-keyword">const</span> userWhoCompletedTods = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(usersIds.map(getAllUserById));
  <span class="hljs-built_in">console</span>.log(userWhoCompletedTods.length);
  <span class="hljs-built_in">console</span>.log(userWhoCompletedTods[<span class="hljs-number">0</span>]);
}
main();
</code></pre>
<p>In the above example, First, we are fetching some todos using the rest API. After that, we are filtering todo based on its status completed. Once we have all complete todos, We are collecting ids and to fetch all users.</p>
<p>All good. However, If we have to change one simple behaviour. Fetch users who have not completed todos. Even though it is simply not changing. But will change all coding declaration. We do have to change all variable name. Which is a tedious job to do. We can make this program more declarative using FP. For that we do need some helper methods:</p>
<p><strong>Helper methods:</strong> <a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/docs/">30-seconds-of-typescript</a></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> curry = <span class="hljs-function">(<span class="hljs-params">fn, arity = fn.length, ...args</span>) =&gt;</span>
  arity &lt;= args.length ? fn(...args) : curry.bind(<span class="hljs-literal">null</span>, fn, arity, ...args);

<span class="hljs-keyword">const</span> filter = <span class="hljs-function">(<span class="hljs-params">fn, data</span>) =&gt;</span> data.filter(fn);
<span class="hljs-keyword">const</span> map = <span class="hljs-function">(<span class="hljs-params">fn, data</span>) =&gt;</span> data.map(fn);
<span class="hljs-keyword">const</span> not = <span class="hljs-function">(<span class="hljs-params">fn</span>) =&gt;</span> (...args) =&gt; !fn(...args);
<span class="hljs-keyword">const</span> prop = curry(<span class="hljs-function">(<span class="hljs-params">key, data</span>) =&gt;</span> data[key]);
</code></pre>
<p>Now let's rewrite the same program</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> isCompleted = <span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> item.completed;
<span class="hljs-keyword">const</span> isNotCompleted = not(isCompleted);
<span class="hljs-keyword">const</span> getId = prop(<span class="hljs-string">"id"</span>);

<span class="hljs-keyword">const</span> userWhoCompletedTodos = map(getId, filter(isCompleted, todos));
<span class="hljs-keyword">const</span> usersWhoNotCompletedIds = map(getId, filter(isNotCompleted, todos));

<span class="hljs-built_in">console</span>.log(userWhoCompletedTodos.length, usersWhoNotCompletedIds.length);
</code></pre>
<p>As you can see, Adding only a few helpers makes it so simple to switch between <code>isCompleted</code> to <code>isNotCompleted</code>. And the same time it is very expressive on its own.</p>
<p><strong>Note:</strong> There are some other aspects of Functional Programming. I have not covered them all. The reason, Either those are too complex for the scope of this article or not relevant to JavaScript itself.</p>
<p><strong>Some worth mentioning concepts:</strong></p>
<ol>
<li>Functional data structures</li>
<li>Handling errors without exceptions</li>
<li>Strictness and laziness(Lazy evaluation)</li>
<li>Functional parallelism(async FP)</li>
<li>Monoids and Functor</li>
<li>Side-effect</li>
</ol>
<h2 id="where-to-go-from-here">Where to go from here</h2>
<p>As I already mentioned, JavaScript is not a fully functional language. Same time as JavaScript developer, We have to use document and window in frontend. So we completely can not ignore impurity. We have to mix and match. Writing function way makes your code more declarative and readable. However, It does add a little bit of complexity in code in term of core concepts. Saying that, If you know the basic concept as described above. You are good to go and write FP. Same time there are multiple articles online. I have listed some of them below. If you really want to learn FP. I will do recommend to write some code in language like <a target="_blank" href="https://www.scala-lang.org/">scala</a>, <a target="_blank" href="https://clojure.org/">clojure</a>, <a target="_blank" href="https://www.haskell.org/">haskell</a>. It will help you to understand the core concepts and idea behind FP.</p>
<p><em><strong>Note:</strong> Due to content length, I have to break this topic in multiple articles. Soon i will publish next part of it.</em></p>
<p><strong>Reference articles:</strong></p>
<ol>
<li><a target="_blank" href="https://opensource.com/article/17/6/functional-javascript#:~:text=Those%20first%2Dclass%20functions%20are,growing%20trend%20toward%20functional%20programming.">An introduction to functional programming in JavaScript</a></li>
<li><a target="_blank" href="https://hackernoon.com/9-functional-programming-concepts-everyone-should-know-uy503u21">9 Functional Programming Concepts Everyone Should Know</a></li>
<li><a target="_blank" href="https://medium.com/swlh/understand-the-key-functional-programming-concepts-bca440f1bcd6">Understand the Key Functional Programming Concepts</a></li>
<li><a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/docs/">30-seconds-of-typescript/</a></li>
<li><a target="_blank" href="https://docs.scala-lang.org/overviews/scala-book/functional-programming.html">scala-book/functional-programming</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/an-introduction-to-the-basic-principles-of-functional-programming-a2c2a15c84/">An-introduction-to-the-basic-principles-of-functional-programming</a></li>
</ol>
]]></content:encoded></item><item><title><![CDATA[10 One-Liner Utility methods in TypeScript/JavaScript]]></title><description><![CDATA[Sometimes you have some duplicate code that you want to share across the project. It does not belong to some particular type. Those type of function and class called utility methods or utility class. Utility methods can be written in one single file ...]]></description><link>https://blog.decipher.dev/10-one-liner-utility-methods-in-typescript-javascript</link><guid isPermaLink="true">https://blog.decipher.dev/10-one-liner-utility-methods-in-typescript-javascript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 06 Apr 2021 16:17:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617725575286/iZFaTU0aL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sometimes you have some duplicate code that you want to share across the project. It does not belong to some particular type. Those type of function and class called utility methods or utility class. Utility methods can be written in one single file or they can be split into multiple files, base on their categorization. I personally prefer, I <code>util</code> folder with multiple files. However, I use a single file for all common small utility functions.</p>
<blockquote>
<p><strong>Note:</strong> <em>All code example has written in TypeScript. You can use <a target="_blank" href="https://www.typescriptlang.org/play">TypeScript Playground</a> to convert TS to JS code. Another thing to note, Sample Example Codes are actually not the one-liner. But all code has only one line logical block.</em> </p>
</blockquote>
<h2 id="how-to-create-a-reusable-utility-module">How to create a reusable utility module</h2>
<p>If you are using TypeScript or Babel in your project, You can use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules"><em>ES6 module</em></a> out of the box.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// util/draw.ts</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> name = <span class="hljs-string">'square'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">area</span>(<span class="hljs-params">length: <span class="hljs-built_in">number</span>, breadth: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">return</span> length * breadth
}
</code></pre>
<p>However, in traditional node.js, ES6 import and export are not supported out of the box. You can use <a target="_blank" href="https://nodejs.org/api/modules.html"><strong>module.exports/exports</strong></a>  to export method or class. </p>
<pre><code class="lang-js"><span class="hljs-comment">// util/draw.js</span>

<span class="hljs-built_in">exports</span>.name = <span class="hljs-string">'square'</span>;

<span class="hljs-built_in">exports</span>.area = <span class="hljs-function">(<span class="hljs-params">length, breadth</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> length * breadth
}
</code></pre>
<p>Once you have the setup ready. You can use the below function in your utility file. </p>
<h2 id="1-array-to-csv">1. Array to CSV</h2>
<p>Converting an array to CSV is a very common operation in the frontend. We do not want to create a server API to perform such a small logical CSV generation. Before generating a CSV file, We need to convert the array to a CSV string. The below util method can help to generate CSV string.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> arrayToCSV = (arr: <span class="hljs-function">(<span class="hljs-params"><span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span></span>)[][], <span class="hljs-params">delimiter</span> = ",") =&gt;</span>
  arr
    .map(<span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span>
      v
        .map(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> (<span class="hljs-keyword">typeof</span> x === <span class="hljs-string">"string"</span> ? <span class="hljs-string">`"<span class="hljs-subst">${x.replace(<span class="hljs-regexp">/"/g</span>, <span class="hljs-string">'""'</span>)}</span>"`</span> : x))
        .join(delimiter)
    )
    .join(<span class="hljs-string">"\n"</span>);
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">arrayToCSV([
  [<span class="hljs-string">"a"</span>, <span class="hljs-string">'"b" great'</span>],
  [<span class="hljs-string">"c"</span>, <span class="hljs-number">3.1415</span>],
]); <span class="hljs-comment">// '"a","""b"" great"\n"c",3.1415'</span>
</code></pre>
<h2 id="2-capitalize">2. Capitalize</h2>
<p>Capitalizes the first letter of a string. you can pass <code>lowerRest</code>, to convert rest characters in lowercase.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> capitalize = (str: <span class="hljs-built_in">string</span> = <span class="hljs-string">""</span>, lowerRest = <span class="hljs-literal">false</span>): <span class="hljs-function"><span class="hljs-params">string</span> =&gt;</span>
  str.slice(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>).toUpperCase() +
  (lowerRest ? str.slice(<span class="hljs-number">1</span>).toLowerCase() : str.slice(<span class="hljs-number">1</span>));
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">capitalize(<span class="hljs-string">"fooBar"</span>); <span class="hljs-comment">// 'FooBar'</span>
capitalize(<span class="hljs-string">"fooBar"</span>, <span class="hljs-literal">true</span>); <span class="hljs-comment">// 'Foobar'</span>
</code></pre>
<h4 id="modified-versionusing-regex-replace">Modified version(using regex, replace)</h4>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> capitalizeEveryWord = <span class="hljs-function">(<span class="hljs-params">str = <span class="hljs-string">""</span></span>) =&gt;</span>
  str.replace(<span class="hljs-regexp">/\b[a-z]/g</span>, <span class="hljs-function">(<span class="hljs-params">char</span>) =&gt;</span> char.toUpperCase());
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">capitalizeEveryWord(<span class="hljs-string">"hello world!"</span>);  <span class="hljs-comment">// 'Hello World!'</span>
</code></pre>
<h2 id="3-castconvert-into-array">3. Cast/Convert into Array</h2>
<p>Casts the provided value as an array if it's not one.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> castArray = (val: <span class="hljs-built_in">any</span>): <span class="hljs-built_in">any</span>[] =&gt;
  <span class="hljs-built_in">Array</span>.isArray(val) ? val : [val];
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">castArray(<span class="hljs-string">"foo"</span>);  <span class="hljs-comment">// ['foo']</span>
castArray([<span class="hljs-number">1</span>]);  <span class="hljs-comment">// [1]</span>
</code></pre>
<h2 id="4-create-chunks-of-array">4. Create chunks of Array</h2>
<p>Chunks an array into smaller arrays of a specified size.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> chunk = <span class="hljs-function">(<span class="hljs-params">arr: <span class="hljs-built_in">any</span>[], size: <span class="hljs-built_in">number</span></span>) =&gt;</span>
  <span class="hljs-built_in">Array</span>.from({ length: <span class="hljs-built_in">Math</span>.ceil(arr.length / size) }, <span class="hljs-function">(<span class="hljs-params">_: <span class="hljs-built_in">any</span>, i: <span class="hljs-built_in">number</span></span>) =&gt;</span>
    arr.slice(i * size, i * size + size)
  );
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">chunk([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>], <span class="hljs-number">2</span>); <span class="hljs-comment">// [[1,2],[3,4],[5]]</span>
</code></pre>
<h2 id="5-create-a-compact-array-by-removing-falsy-values">5. Create a compact Array by removing falsy values</h2>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> compact = <span class="hljs-function">(<span class="hljs-params">arr: <span class="hljs-built_in">any</span>[]</span>) =&gt;</span> arr.filter(<span class="hljs-built_in">Boolean</span>);
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">compact([<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-literal">false</span>, <span class="hljs-number">2</span>, <span class="hljs-string">""</span>, <span class="hljs-number">3</span>, <span class="hljs-string">"a"</span>, <span class="hljs-built_in">Number</span>(<span class="hljs-string">"e"</span>) * <span class="hljs-number">23</span>, <span class="hljs-literal">NaN</span>, <span class="hljs-string">"s"</span>, <span class="hljs-number">34</span>]); <span class="hljs-comment">// [ 1, 2, 3, 'a', 's', 34 ]</span>
</code></pre>
<h2 id="6-string-contains">6. String contains</h2>
<p>Returns true if given string s1 contains s2. Compare is case insensitive.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> contains = <span class="hljs-function">(<span class="hljs-params">s1: <span class="hljs-built_in">string</span>, s2: <span class="hljs-built_in">string</span> = <span class="hljs-string">""</span></span>) =&gt;</span>
  s1.toLowerCase().indexOf(s2.toLowerCase()) !== <span class="hljs-number">-1</span>;
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">contains(<span class="hljs-string">"Text1"</span>, <span class="hljs-string">"Ext"</span>); <span class="hljs-comment">// true</span>
contains(<span class="hljs-string">"Text1"</span>, <span class="hljs-string">"et"</span>); <span class="hljs-comment">// false</span>
</code></pre>
<h2 id="7-convert-csv-string-to-2d-array">7. Convert CSV string to 2D Array</h2>
<p>Converts a comma-separated values (CSV) string to a 2D array.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> CSVToArray = <span class="hljs-function">(<span class="hljs-params">data: <span class="hljs-built_in">string</span>, delimiter = <span class="hljs-string">","</span>, omitFirstRow = <span class="hljs-literal">false</span></span>) =&gt;</span>
  data
    .slice(omitFirstRow ? data.indexOf(<span class="hljs-string">"\n"</span>) + <span class="hljs-number">1</span> : <span class="hljs-number">0</span>)
    .split(<span class="hljs-string">"\n"</span>)
    .map(<span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> v.split(delimiter));
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">CSVToArray(<span class="hljs-string">"a,b\nc,d"</span>); <span class="hljs-comment">// [['a','b'],['c','d']];</span>
CSVToArray(<span class="hljs-string">"a;b\nc;d"</span>, <span class="hljs-string">";"</span>); <span class="hljs-comment">// [['a','b'],['c','d']];</span>
CSVToArray(<span class="hljs-string">"col1,col2\na,b\nc,d"</span>, <span class="hljs-string">","</span>, <span class="hljs-literal">true</span>); <span class="hljs-comment">// [['a','b'],['c','d']];</span>
</code></pre>
<h2 id="8-deep-flatten-array">8. Deep Flatten Array</h2>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> deepFlatten = (arr: <span class="hljs-built_in">any</span>[]): <span class="hljs-built_in">any</span>[] =&gt; {
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">Array</span>.prototype.flat !== <span class="hljs-string">"undefined"</span>) <span class="hljs-keyword">return</span> arr.flat(<span class="hljs-literal">Infinity</span>);
  <span class="hljs-keyword">return</span> [].concat(
    ...arr.map(<span class="hljs-function">(<span class="hljs-params">v: <span class="hljs-built_in">any</span></span>) =&gt;</span> (<span class="hljs-built_in">Array</span>.isArray(v) ? deepFlatten(v) : v))
  );
};
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">deepFlatten([<span class="hljs-number">1</span>, [<span class="hljs-number">2</span>], [[<span class="hljs-number">3</span>], <span class="hljs-number">4</span>], <span class="hljs-number">5</span>]); <span class="hljs-comment">// [1, 2, 3, 4, 5]</span>
deepFlatten([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, [<span class="hljs-number">5</span>, <span class="hljs-number">6</span>, [<span class="hljs-number">7</span>, <span class="hljs-number">8</span>, [<span class="hljs-number">9</span>, <span class="hljs-number">10</span>]]]]]); <span class="hljs-comment">// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</span>
</code></pre>
<p><strong>Note: </strong> You can also use ES2017 API to flatten Array.</p>
<pre><code class="lang-ts">[<span class="hljs-number">1</span>, [<span class="hljs-number">2</span>], [[<span class="hljs-number">3</span>], <span class="hljs-number">4</span>], <span class="hljs-number">5</span>].flat(<span class="hljs-literal">Infinity</span>)
</code></pre>
<h2 id="9-ellipsis-or-truncates-strings">9. Ellipsis or Truncates Strings</h2>
<p>Truncates a string up to a specified length.</p>
<p>Determine if the string's length is greater than num. Return the string truncated to the desired length, with '...' appended to the end of the original string.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> ellipsis = <span class="hljs-function">(<span class="hljs-params">str: <span class="hljs-built_in">string</span>, num: <span class="hljs-built_in">number</span> = str.length, ellipsisStr = <span class="hljs-string">"..."</span></span>) =&gt;</span>
  str.length &gt;= num
    ? str.slice(<span class="hljs-number">0</span>, num &gt;= ellipsisStr.length ? num - ellipsisStr.length : num) +
      ellipsisStr
    : str;
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">ellipsis(<span class="hljs-string">"boomerang"</span>, <span class="hljs-number">5</span>, <span class="hljs-string">".."</span>); <span class="hljs-comment">// "boo.."</span>

ellipsis(<span class="hljs-string">"boomerang"</span>); <span class="hljs-comment">// "boomer..."</span>

ellipsis(<span class="hljs-string">"boomerang"</span>, <span class="hljs-literal">undefined</span>, <span class="hljs-string">"♦♦♦"</span>); <span class="hljs-comment">// "boomer♦♦♦"</span>
</code></pre>
<h2 id="10-group-data-by-the-key-or-function">10. Group data by the key or function</h2>
<p>Groups the elements of an array based on the given function.</p>
<p>Use Array.prototype.map() to map the values of an array to a function or property name. Use Array.prototype.reduce() to create an object, where the keys are produced from the mapped results.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">type</span> MapFunc&lt;T = <span class="hljs-built_in">any</span>&gt; = <span class="hljs-function">(<span class="hljs-params">val: T, index?: <span class="hljs-built_in">number</span>, arr?: T[]</span>) =&gt;</span> T;

<span class="hljs-keyword">const</span> groupBy = &lt;T = <span class="hljs-built_in">any</span>&gt;<span class="hljs-function">(<span class="hljs-params">arr: T[], fn: MapFunc&lt;T&gt; | <span class="hljs-built_in">string</span></span>) =&gt;</span>
  arr.map(isString(fn) ? <span class="hljs-function">(<span class="hljs-params">val: <span class="hljs-built_in">any</span></span>) =&gt;</span> val[fn] : fn).reduce(<span class="hljs-function">(<span class="hljs-params">acc, val, i</span>) =&gt;</span> {
    acc[val] = (acc[val] || []).concat(arr[i]);
    <span class="hljs-keyword">return</span> acc;
  }, {});
</code></pre>
<p><strong>How to use:</strong></p>
<pre><code class="lang-ts">groupBy([<span class="hljs-number">6.1</span>, <span class="hljs-number">4.2</span>, <span class="hljs-number">6.3</span>], <span class="hljs-built_in">Math</span>.floor); <span class="hljs-comment">// {4: [4.2], 6: [6.1, 6.3]}</span>
groupBy([<span class="hljs-string">"one"</span>, <span class="hljs-string">"two"</span>, <span class="hljs-string">"three"</span>], <span class="hljs-string">"length"</span>); <span class="hljs-comment">// {3: ['one', 'two'], 5: ['three']}</span>
</code></pre>
<h3 id="conclusion">Conclusion:</h3>
<p>After writing the 10 method example, I realized that I could not cover all the One-Liner util in one post. Same time I could not pick the best of 10 among them all. So I will try to cover the rest in another Article. If your willing to spend some spare time. You can find your best utility method here on my website <a target="_blank" href="https://decipher.dev/30-seconds-of-typescript/">30 Seconds of Typescript</a>.</p>
<p>Please let me know your best in the comments. If you have your own version of the one-liner. Please do let me know, I will include it on my website as well as in my next article.</p>
<p><em>Thanks for reading. If you like, Please share and react to my article. </em></p>
]]></content:encoded></item><item><title><![CDATA[Golang for Frontend developers | Beginner guide to Golang]]></title><description><![CDATA[Are you a beginner and you want to start Golang but don't know how?
You have written express.js code and want to create micro-services using Golang? 

Then this article is for you. This article will guide you step by step building block to build a sc...]]></description><link>https://blog.decipher.dev/golang-for-frontend-developers-a-beginner-guide-to-golang</link><guid isPermaLink="true">https://blog.decipher.dev/golang-for-frontend-developers-a-beginner-guide-to-golang</guid><category><![CDATA[Go Language]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Thu, 01 Apr 2021 10:56:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1616690591190/xCLleIUJV.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ul>
<li>Are you a beginner and you want to start Golang but don't know how?</li>
<li>You have written <code>express.js</code> code and want to create micro-services using Golang? </li>
</ul>
<p>Then this article is for you. This article will guide you step by step building block to build a scalable Golang project but in simple words.</p>
<h2 id="do-i-really-need-golang">Do I really need Golang?</h2>
<p>Before going further you should ask this question to yourself and your teammates. Hope you are not migrating just for the sake that you want to try out something new. Golang is a new language but it is not that new. The first stable release was in 2009 the same as nodejs. Due to similarity or say javascript popularity, Nodejs become famous in a few years. React, Angular and other frontend framework help to make nodejs one of the popular language in the market. </p>
<p>Golang has a different type of fans. Just like any other stable language, it took time for Golang to become famous. Now it is a buzz word in all industries. However, Golang is not just a buzz word. It has defiantly the potential to become the first choice and it is happing already. Now Golang is the first choice for micro-service development. </p>
<p>The biggest reason for adaptation, This language is maintained by Google Team. And companies like Netflix, Google, Facebook are using it in production <a target="_blank" href="https://github.com/golang/go/wiki/GoUsers">read more</a>. Tools like <a target="_blank" href="https://www.docker.com/">Docker</a> and <a target="_blank" href="https://kubernetes.io/">kubernetes</a> has been written on Golang. Due to its high performance, simplicity it is now goto go language. </p>
<p><strong>You can ask me a question. If Golang is so good and it is in the market for such a long time why I am writing this blog now?</strong>
The answer is simple, Recently one of my tool build on Golang went live in my Organization. So I want to share my experience.</p>
<h2 id="prerequisite">Prerequisite</h2>
<ul>
<li><strong>Golang[v1.16 and above]:</strong> You should have the latest version of Golang in your system. You can download and install Golang <a target="_blank" href="https://golang.org/doc/install">here</a>.</li>
<li>Basic understanding of async programming</li>
<li>Basic understanding of functional programming</li>
<li>Linux/Unix: Since the examples and command will be written for the UNIX system. You can find similar command if you are working on a window system</li>
</ul>
<h3 id="verify-golang">Verify Golang</h3>
<p>To verify, open and type the below command </p>
<pre><code class="lang-bash">go version

<span class="hljs-comment">## output</span>
go version go1.16.1 darwin/amd64
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617273449209/NCPiSaJOg.jpeg" alt="golang-introduction-hello-world.jpeg" /></p>
<h2 id="golang-first-program-hello-golang">Golang First program, "Hello, Golang ❤️"</h2>
<p>Writing a Golang program is pretty simple. You can create a file with "package main".</p>
<pre><code class="lang-bash">touch main.go
</code></pre>
<p>Add below code in <code>main.go</code></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    fmt.Println(<span class="hljs-string">"Hello, Golang ❤️"</span>)
}
</code></pre>
<p>Running a Golang program: <code>go run main.go</code></p>
<p><strong>Explanation:</strong> Every Go Executable program required an entry file which should be defined in package main. And file should contain a <code>main function</code>. </p>
<p><strong>Note:</strong> Golang is a compile and statically typed language, meaning you need to compile the program before running it. However, when you run an app using <code>go run</code> command. It creates a binary in the temp folder and executes it. In production, You should do this by own. You should not run an app using Go run.</p>
<h4 id="running-app-using-the-build-command">Running app using the build command</h4>
<pre><code class="lang-bash"><span class="hljs-comment">## compile and build go app[You can give any name to executable using -o]</span>
go build -o todo_app.exe main.go 

<span class="hljs-comment">#### running a go app</span>

./todo_app.exe
</code></pre>
<h4 id="clean-up-gitignore-setup-optional">Clean up, Gitignore setup [optional]</h4>
<pre><code class="lang-bash"><span class="hljs-comment">## .gitignore</span>

<span class="hljs-comment"># Binaries for programs and plugins</span>
*.exe
*.exe~
*.dll
*.so
*.dylib

<span class="hljs-comment"># Test binary, built with `go test -c`</span>
*.<span class="hljs-built_in">test</span>

<span class="hljs-comment"># Output of the go coverage tool, specifically when used with LiteIDE</span>
*.out

<span class="hljs-comment"># Dependency directories (remove the comment below to include it)</span>
<span class="hljs-comment"># vendor/</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617273749533/HOT8MwfMU.jpeg" alt="manager.jpeg" /></p>
<h2 id="golang-package-manager-start-a-new-project">Golang package manager, Start a new project</h2>
<p>In version 1.11, Go introduce a new package manager similar to nodejs npm. This makes it easier to start a new project. To start a new project, You can create a folder and follow the below command.</p>
<pre><code class="lang-bash">mkdir todo_app
<span class="hljs-built_in">cd</span> todo_app
go mod init github.com/deepakshrma/todo_app
</code></pre>
<p><strong>Explanation:</strong> Here in the above code, You have created a folder. And just like node(npm) init. You have initialized a module with the name <code>github.com/deepakshrma/todo_app</code>. The module name can be anything. However, It is recommended to use your module hosting platform(here, in this case, github.com) followed by the username and app name. </p>
<p>Once you run the above command You can see a file will be created with the name <code>go.mod</code>. This will have all the dependencies and settings required by this app. You can read more on <code>go.mod</code> <a target="_blank" href="https://golang.org/doc/modules/managing-dependencies">here</a>. You can also watch <a target="_blank" href="https://www.youtube.com/watch?v=Z1VhG7cf83M">EVERYTHING You SHOULD know about Go Modules </a>, a nice video tutorial on youtube.</p>
<pre><code class="lang-bash">cat go.mod

<span class="hljs-comment">## output</span>
module github.com/deepakshrma/todo_app

go 1.16
</code></pre>
<h2 id="golang-task-manager-build-something-new">Golang task manager, Build something new</h2>
<p>Golang does not have an in-built task manager like the npm package. However, there is plenty of third-party modules available in the Golang world. I tried <a target="_blank" href="https://taskfile.dev/#/">go-task</a> module and I loved it. So we can use the same.</p>
<h4 id="create-a-taskfileyml-in-root-folder">Create a <code>Taskfile.yml</code> in root folder</h4>
<pre><code class="lang-YAML"><span class="hljs-attr">version:</span> <span class="hljs-string">"3"</span>

<span class="hljs-attr">tasks:</span>
  <span class="hljs-attr">build-app:</span>
    <span class="hljs-attr">cmds:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">go</span> <span class="hljs-string">build</span> <span class="hljs-string">-o</span> <span class="hljs-string">todo_app.exe</span> <span class="hljs-string">main.go</span>
    <span class="hljs-attr">silent:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>To use <a target="_blank" href="https://taskfile.dev/#/">go-task</a>, you have to install the binary. There are many ways you can install <code>task</code> binary. However, I recommend using the command <code>go get -u github.com/go-task/task/v3/cmd/task</code>. It will download go-task and create a binary in GOPATH. After that, you can use the task command globally.</p>
<h4 id="build-using-task">Build using task</h4>
<pre><code class="lang-bash">task build-app
</code></pre>
<h2 id="write-your-first-micro-service">Write your first micro-service</h2>
<p>A micro-service(web service) can follow different architecture. For the demo, I will use the RESTfull API. You can find relevant doc for GRPC <a target="_blank" href="https://grpc.io/">here</a>.</p>
<p>Update <code>main.go</code> file</p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-comment">// import net/http module</span>

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"log"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"os"</span>
)

<span class="hljs-comment">// Route function to handle the request</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">handleFunc</span><span class="hljs-params">(w http.ResponseWriter, req *http.Request)</span></span> {
    fmt.Fprint(w, <span class="hljs-string">"Hello, Golang ❤️"</span>)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-comment">// Get the user provided port from ENV, if port is not defined user default port as 8080</span>
    port := os.Getenv(<span class="hljs-string">"PORT"</span>)
    <span class="hljs-keyword">if</span> port == <span class="hljs-string">""</span> {
        port = <span class="hljs-string">"8080"</span>
    }

    <span class="hljs-comment">// Bind "/" as route to handleFunc</span>
    http.HandleFunc(<span class="hljs-string">"/"</span>, handleFunc)

    log.Printf(<span class="hljs-string">"You app is running on http://localhost:%s"</span>, port)

    <span class="hljs-comment">// Listen and Serve to localhost:port</span>
    log.Fatal(http.ListenAndServe(fmt.Sprintf(<span class="hljs-string">":%s"</span>, port), <span class="hljs-literal">nil</span>))
}
</code></pre>
<p>Add a task to <code>Tasklist.yml</code></p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">"3"</span>

<span class="hljs-attr">tasks:</span>
<span class="hljs-comment">## rest of the tasks</span>
  <span class="hljs-attr">build-start:</span>
    <span class="hljs-attr">cmds:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">go</span> <span class="hljs-string">build</span> <span class="hljs-string">-o</span> <span class="hljs-string">todo_app.exe</span> <span class="hljs-string">main.go</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">./todo_app.exe</span>
</code></pre>
<p><strong>Run app: </strong> Once you add the task, You can build and run the app using the command <code>task build-start</code>. After that, you can open the URL to any browser <a target="_blank" href="http://localhost:8080">http://localhost:8080</a> to see your first RESTfull API.</p>
<h2 id="implementing-database-repository">Implementing database repository</h2>
<p>This article is just starting guideline. So, We will not use a real database to make the connection and save data. However to mimic the database let's create a repository. We will use an in-memory <code>array/slice</code> to contain data.</p>
<p>To create a simple database repository and add methods to insert and list Todo, Add the below code to the <code>todo_app/repository/repository.go</code> file. </p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> repository

<span class="hljs-keyword">import</span> <span class="hljs-string">"time"</span>

<span class="hljs-keyword">type</span> Todo <span class="hljs-keyword">struct</span> {
    Title       <span class="hljs-keyword">string</span>    <span class="hljs-string">`json:"title"`</span>
    Done        <span class="hljs-keyword">bool</span>      <span class="hljs-string">`json:"done"`</span>
    Description <span class="hljs-keyword">string</span>    <span class="hljs-string">`json:"description"`</span>
    CreatedAt   time.Time <span class="hljs-string">`json:"createdAt"`</span>
}

<span class="hljs-keyword">type</span> repository <span class="hljs-keyword">struct</span> {
    db []Todo
}

<span class="hljs-keyword">var</span> (
    r *repository
)

<span class="hljs-comment">// This function will run one time when package is imported before anything else.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">init</span><span class="hljs-params">()</span></span> {
    r = &amp;repository{
        db: []Todo{},
    }
}

<span class="hljs-comment">// Repository, Create public interface</span>
<span class="hljs-keyword">type</span> Repository <span class="hljs-keyword">interface</span> {
    ListTodo() []Todo
    AddTodo(todo *Todo) Todo
}

<span class="hljs-comment">// Repository, Get instance of singleton repository</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewRepository</span><span class="hljs-params">()</span> <span class="hljs-title">Repository</span></span> {
    <span class="hljs-keyword">return</span> r
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *repository)</span> <span class="hljs-title">ListTodo</span><span class="hljs-params">()</span> []<span class="hljs-title">Todo</span></span> {
    <span class="hljs-keyword">return</span> r.db
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(r *repository)</span> <span class="hljs-title">AddTodo</span><span class="hljs-params">(todo *Todo)</span> <span class="hljs-title">Todo</span></span> {
    todo.CreatedAt = time.Now()
    r.db = <span class="hljs-built_in">append</span>(r.db, *todo)
    <span class="hljs-keyword">return</span> *todo
}
</code></pre>
<p>Here in the above code, We have exposed a <a target="_blank" href="https://github.com/golang/lint/issues/210">singleton instance</a> of Repository. </p>
<p><strong>Let's tryout in main.go, we will remove this code later</strong></p>
<pre><code class="lang-go"> <span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>

    <span class="hljs-string">"github.com/deepakshrma/todo_app/repository"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    r := repository.NewRepository()
    r.AddTodo(&amp;repository.Todo{
        Title:       <span class="hljs-string">"Write a blog on golang"</span>,
        Description: <span class="hljs-string">"//TODO"</span>,
        Done:        <span class="hljs-literal">false</span>,
    })
    todos := r.ListTodo()
    <span class="hljs-keyword">for</span> _, todo := <span class="hljs-keyword">range</span> todos {
        fmt.Printf(<span class="hljs-string">"%+v\n"</span>, todo)
    }
}
</code></pre>
<p>If you try the above code in the main function, You will see come output <code>{Title: Write a blog on Golang Done:false Description://TODO CreatedAt:2021-03-27 14:16:00.03263 +0800 +08 m=+0.000465414}</code>. We will update our router later.</p>
<h2 id="using-a-third-party-modulepackage">Using a third-party module/package</h2>
<p>We have created a simple route using <code>http.HandleFunc</code>. But managing multiple routes could be a challenge. And at the same time, we don't want to re-invent the wheel. Using a module in Golang is pretty simple. You can get any module from the Github repo. Let's use one of the best web framework modules <a target="_blank" href="https://github.com/gin-gonic/gin">gin-gonic</a>.</p>
<p>To get a go module, you can use <code>go get</code> command or you can use <code>go mod tidy</code> after adding code. </p>
<pre><code class="lang-go"><span class="hljs-comment">// main.go</span>

<span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"log"</span>
    <span class="hljs-string">"net/http"</span>
    <span class="hljs-string">"os"</span>

    <span class="hljs-string">"github.com/deepakshrma/todo_app/repository"</span>
    <span class="hljs-string">"github.com/gin-gonic/gin"</span>
)

<span class="hljs-keyword">var</span> (
    r = repository.NewRepository()
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">GetTodos</span><span class="hljs-params">(c *gin.Context)</span></span> {
    c.JSON(http.StatusOK, gin.H{<span class="hljs-string">"data"</span>: r.ListTodo()})
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">AddTodo</span><span class="hljs-params">(c *gin.Context)</span></span> {
    <span class="hljs-keyword">var</span> input repository.Todo
    <span class="hljs-keyword">if</span> err := c.ShouldBindJSON(&amp;input); err != <span class="hljs-literal">nil</span> {
        c.JSON(http.StatusBadRequest, gin.H{<span class="hljs-string">"error"</span>: err.Error()})
        <span class="hljs-keyword">return</span>
    }
    r.AddTodo(&amp;input)
    c.JSON(http.StatusOK, gin.H{<span class="hljs-string">"data"</span>: input})
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Get the user provided port from ENV, if port is not defined user default port as 8080</span>
    port := os.Getenv(<span class="hljs-string">"PORT"</span>)
    <span class="hljs-keyword">if</span> port == <span class="hljs-string">""</span> {
        port = <span class="hljs-string">"8080"</span>
    }
    router := gin.Default()
    v1 := router.Group(<span class="hljs-string">"/v1"</span>)
    {
        v1.GET(<span class="hljs-string">"/todos"</span>, GetTodos)
        v1.POST(<span class="hljs-string">"/todos"</span>, AddTodo)
    }
    log.Fatal(router.Run(fmt.Sprintf(<span class="hljs-string">":%s"</span>, port)))
}
</code></pre>
<p>Run <code>go mod tidy</code> command and start the server</p>
<pre><code class="lang-bash"><span class="hljs-comment">## get modules</span>
go mod tidy

<span class="hljs-comment">## build and start the server</span>
 task build-start
</code></pre>
<p><strong>Note:</strong> <code>go mod tidy</code> import module and same time clean up <code>go.mod</code> file by removing unused imports. It is a very handy command.</p>
<p><strong>Explanation:</strong> Above code we have created a gin router with grouping them using API versioning. If you dot use Group, The default endpoint will be "/todos". But adding Group <code>v1</code>, Now all APIs need to add <code>v1</code> to request resources.</p>
<h4 id="insert-a-todo-and-get-the-list-using-curl">Insert a todo and get the list using curl</h4>
<p>You can use postman to insert and get data. However, for simplicity, I will use the curl command.</p>
<p><strong>Insert data using endpoint</strong></p>
<pre><code class="lang-bash">curl --header <span class="hljs-string">"Content-Type: application/json"</span> \
  --request POST \
  --data <span class="hljs-string">'{"title":"Create Golang Tutorial","Description":"lets do it.."}'</span> \
  http://localhost:8080/v1/todos
</code></pre>
<pre><code class="lang-json"><span class="hljs-comment">// result</span>

{<span class="hljs-attr">"data"</span>:{<span class="hljs-attr">"title"</span>:<span class="hljs-string">"Create Golang Tutorial"</span>,<span class="hljs-attr">"done"</span>:<span class="hljs-literal">false</span>,<span class="hljs-attr">"description"</span>:<span class="hljs-string">"lets do it.."</span>,<span class="hljs-attr">"createdAt"</span>:<span class="hljs-string">"2021-03-27T14:54:56.796403+08:00"</span>}}
</code></pre>
<p><strong>Fetch data using endpoint</strong></p>
<pre><code class="lang-bash">curl http://localhost:8080/v1/todos
</code></pre>
<pre><code class="lang-json"><span class="hljs-comment">// result</span>

{<span class="hljs-attr">"data"</span>:[{<span class="hljs-attr">"title"</span>:<span class="hljs-string">"Create Golang Tutorial"</span>,<span class="hljs-attr">"done"</span>:<span class="hljs-literal">false</span>,<span class="hljs-attr">"description"</span>:<span class="hljs-string">"lets do it.."</span>,<span class="hljs-attr">"createdAt"</span>:<span class="hljs-string">"2021-03-27T14:54:56.796403+08:00"</span>}]}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617273718465/5RATYEivE.jpeg" alt="how to write a research paper conclusion (1)_1554820948.jpeg" /></p>
<h2 id="conclusions-where-to-go-from-here">Conclusions, Where to go from here</h2>
<p>Finally, We have a working Micro Service. Definitely, This is not the perfect one. There are some other topics that need to be cover like Testing. However, It will give a kick start to write code in Golang. And thanks to the good community, You will find lots of nice document over the internet written by experts. Some article has been listed below.</p>
<h4 id="references">References:</h4>
<ul>
<li><a target="_blank" href="https://golang.org/doc/tutorial/getting-started">getting-started</a></li>
<li><a target="_blank" href="https://golang.org/doc/effective_go">effective_go</a></li>
<li><a target="_blank" href="https://gobyexample.com">gobyexample</a></li>
<li><a target="_blank" href="https://www.codeproject.com/Articles/5261771/Golang-SQLite-Simple-Example">Golang-SQLite-Simple-Example</a></li>
<li><a target="_blank" href="http://blog.ralch.com/tutorial/design-patterns/golang-singleton/">design-patterns</a></li>
<li><a target="_blank" href="https://blog.logrocket.com/how-to-build-a-rest-api-with-golang-using-gin-and-gorm/">golang-using-gin</a></li>
</ul>
<p><strong>Source Code:</strong></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/deepakshrma/golang-basics/tree/main/todo_app">https://github.com/deepakshrma/golang-basics/tree/main/todo_app</a></div>
<p><strong>Quotes Of The Day:</strong></p>
<blockquote>
<p>Writing a micro-server is an art and to make good Art, Artist needs a good tool. Go is one of those tools. - Me 😂</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Everything you should know about JavaScript | Breaking a Loop]]></title><description><![CDATA[JavaScript is not only weird but confusing and ambiguous as well. The more you work and debug the more you find a new thing. The weirdness of JavaScript is one of how to break a loop. Here are a few ways to break a loop in JavaScript.
First, let’s se...]]></description><link>https://blog.decipher.dev/everything-you-should-know-about-javascript-or-breaking-a-loop</link><guid isPermaLink="true">https://blog.decipher.dev/everything-you-should-know-about-javascript-or-breaking-a-loop</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[clean code]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Mon, 29 Mar 2021 03:12:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1616987519539/VNuySRav3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript is not only weird but confusing and ambiguous as well. The more you work and debug the more you find a new thing. The weirdness of JavaScript is one of <strong>how to break a loop</strong>. Here are a few ways to break a loop in JavaScript.</p>
<p>First, let’s see what are the different ways to create a loop and break a loop.</p>
<h2 id="1-traditional-for-while-do-while-loop">1. Traditional <em>for</em>, <em>while</em>, <em>do-while</em> loop</h2>
<p>Creating a <strong>for-loop</strong> is very easy and very common.</p>
<p><strong>For Loop:</strong></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">howMany</span>(<span class="hljs-params">selectObject</span>) </span>{
  <span class="hljs-keyword">let</span> numberSelected = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; selectObject.options.length; i++) {
    <span class="hljs-keyword">if</span> (selectObject.options[i].selected) {
      numberSelected++;
    }
  }
  <span class="hljs-keyword">return</span> numberSelected;
}
</code></pre>
<p><strong>Do While:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>;
<span class="hljs-keyword">do</span> {
  i += <span class="hljs-number">1</span>;
  <span class="hljs-built_in">console</span>.log(i);
} <span class="hljs-keyword">while</span> (i &lt; <span class="hljs-number">5</span>);
<span class="hljs-comment">// While</span>
<span class="hljs-keyword">let</span> n = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> x = <span class="hljs-number">0</span>;
<span class="hljs-keyword">while</span> (n &lt; <span class="hljs-number">3</span>) {
  n++;
  x += n;
}
</code></pre>
<p><strong>How to break:</strong> Breakin a loop is very easy here. You can use <em>break</em> keyword to break a loop.</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; a.length; i++) {
  <span class="hljs-keyword">if</span> (a[i] === theValue) {
    <span class="hljs-keyword">break</span>;
  }
}
</code></pre>
<p>This is a more elegant way of breaking a loop. If you have a nested loop(loop inside the loop). You can use the <em><strong>labelled statement</strong></em> to break a loop.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">labeledLoop</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> x = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> z = <span class="hljs-number">0</span>;
  outer: <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Outer loops: "</span> + x);
    x += <span class="hljs-number">1</span>;
    z = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Inner loops: "</span> + z);
      z += <span class="hljs-number">1</span>;
      <span class="hljs-keyword">if</span> (z === <span class="hljs-number">10</span> &amp;&amp; x === <span class="hljs-number">10</span>) {
        <span class="hljs-keyword">break</span> outer;
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (z === <span class="hljs-number">10</span>) {
        <span class="hljs-keyword">break</span>;
      }
    }
  }
}
</code></pre>
<p>Here <strong>outer</strong> is a label given to outer-loop. Whenever the condition matches, we break the outer loop using the labeled condition.</p>
<p><strong>Note:</strong> Using the <strong>labelled statement</strong> is a nice way but it is a little bit confusing for developers. It is like a <strong>goto</strong> statement that should be avoided. The same result we can get by <em>introducing normal conditional variables</em>.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">conditionalBreak</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> x = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> z = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Outer loops: "</span> + x);
    x += <span class="hljs-number">1</span>;
    z = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">let</span> breakOuterLoop = <span class="hljs-literal">false</span>;
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Inner loops: "</span> + z);
      z += <span class="hljs-number">1</span>;
      <span class="hljs-keyword">if</span> (z === <span class="hljs-number">10</span> &amp;&amp; x === <span class="hljs-number">10</span>) {
        breakOuterLoop = <span class="hljs-literal">true</span>;
        <span class="hljs-keyword">break</span>;
      } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (z === <span class="hljs-number">10</span>) {
        <span class="hljs-keyword">break</span>;
      }
    }
    <span class="hljs-keyword">if</span> (breakOuterLoop) <span class="hljs-keyword">break</span>;
  }
}
</code></pre>
<p>Here in the above code, We have introduced a variable <strong>breakOuterLoop</strong> and I check the value of it after each iteration of the outer loop.</p>
<p><strong>Benchmark</strong>: You may say that introducing a variable and condition can slow down the code. However you may surprise when I say, The <code>**conditionalBreak**</code> is faster than <code>**labeledLoop**</code> in the benchmark.</p>
<p><strong>benchmark:</strong></p>
<pre><code class="lang-bash">labeledLoop x 9,295,537 ops/sec ±0.85% (87 runs sampled)
conditionalBreak x 9,349,901 ops/sec ±0.45% (89 runs sampled)
Fastest is conditionalBreak,labeledLoop
</code></pre>
<p><strong>Test Script:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> { Benchmark } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"benchmark"</span>);
<span class="hljs-keyword">var</span> suite = <span class="hljs-keyword">new</span> Benchmark.Suite();
suite.add(<span class="hljs-string">"labeledLoop"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  labeledLoop();
});
suite.add(<span class="hljs-string">"conditionalBreak"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  conditionalBreak();
});
suite.on(<span class="hljs-string">"cycle"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">String</span>(event.target));
});
suite
  .on(<span class="hljs-string">"complete"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Fastest is "</span> + <span class="hljs-built_in">this</span>.filter(<span class="hljs-string">"fastest"</span>).map(<span class="hljs-string">"name"</span>));
  })
  .run({ <span class="hljs-attr">async</span>: <span class="hljs-literal">true</span> });
</code></pre>
<blockquote>
<p><strong>Note</strong>: I am using <a target="_blank" href="https://benchmarkjs.com/">benchmarkjs</a></p>
</blockquote>
<p><img src="https://miro.medium.com/max/1400/1*Q9iKYn-x3Fsu0ohQat5Scw.png" /></p>
<h3 id="2-array-functional-api-methods">2. Array Functional API methods</h3>
<p>As you know, We should try to use more Array's APIs. <strong><em>Array's API</em></strong> for looping is much cleaner and safer. However, breaking Array's methods are tricky.</p>
<p>If you want to read more on for-loops and understand when to use which loop. Here is an article that you can follow.  <a target="_blank" href="https://blog.decipher.dev/are-for-loops-or-foreach-better-in-javascript">Are For Loops or ForEach Better in JavaScript?</a></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span>(v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">break</span>; <span class="hljs-comment">//Error here: Illegal break statement</span>
  }
  <span class="hljs-built_in">console</span>.log(v)
}
data.forEach(printValueTill5)
</code></pre>
<p><strong>Note:</strong> You can’t use <strong>break</strong> keyword inside a function. Either is <strong>named</strong> function of <strong>anonymous</strong> function. Same time, You can't use <strong>return</strong> false or anything like that. It is considered as returning from the given function. So the code will behave like a <strong>continued</strong> statement.</p>
<pre><code class="lang-js"><span class="hljs-comment">// using return</span>
<span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span>(v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
  }
  <span class="hljs-built_in">console</span>.log(v)
}
data.forEach(printValueTill5)
<span class="hljs-comment">// Output: 1 2 3 4 6 7</span>
</code></pre>
<p><strong> Solution via throwing error:</strong> You can use a <strong>throw</strong> statement to break the loop. However, it is not an elegant way.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> BREAK_LOOP_ERROR = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">"BREAK_LOOP"</span>);
<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">throw</span> BREAK_LOOP_ERROR;
  }
  <span class="hljs-built_in">console</span>.log(v);
};

<span class="hljs-keyword">try</span> {
  data.forEach(printValueTill5);
} <span class="hljs-keyword">catch</span> (e) {
  <span class="hljs-keyword">if</span> (e !== BREAK_LOOP_ERROR) <span class="hljs-keyword">throw</span> e;
  <span class="hljs-built_in">console</span>.debug(e);
}
</code></pre>
<p>Throwing an error in the loop is an anti-pattern. Same time, If you notice how much <strong>boilerplate</strong> code we have to write every time using the throw statement.</p>
<p><strong>Using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every">Array#every</a></strong>: If you are familiar with <strong>[].every()</strong>, It is more eligant way to break a for loop in a functional way.</p>
<pre><code class="lang-js"><span class="hljs-comment">// using </span>
<span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>; <span class="hljs-comment">// return false to break</span>
  }
  <span class="hljs-built_in">console</span>.log(v);
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>; <span class="hljs-comment">// Else continue.</span>
};
data.every(printValueTill5)
</code></pre>
<p>The method <strong>every</strong> will loop over till you return <strong>true</strong>. Once you <strong>return false</strong>, It will break the loop.</p>
<p><strong>Note</strong>: Using <strong>every</strong> is one of the best ways to <strong>break</strong> loops. However, This solution has a lot of cons.</p>
<p><strong>a.</strong> Every method returns a <strong>boolean</strong> either true or false at the end, So you can chain further.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
  <span class="hljs-built_in">console</span>.log(v);
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
};
data.every(printValueTill5) <span class="hljs-comment">// returns false</span>
  .map(<span class="hljs-built_in">console</span>.log) <span class="hljs-comment">// Error: data.every(...).map is not a function</span>
</code></pre>
<p><strong>b.</strong> You have to change the functionality of <strong>printValueTill5</strong> by introducing conditional return. Hard to reuse further.</p>
<p><strong>c.</strong> It is hard to debug and test.</p>
<blockquote>
<p>So now the question remains the same, <strong>“How do you break a loop in JavaScript?”</strong></p>
</blockquote>
<p><strong>The best way, You can create a <strong>utility</strong> method, which is given below. It may not be as performant as the above solutions. But more clean and predictable.</strong></p>
<p><strong>tillWhen:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> _ = {};

<span class="hljs-comment">// fn: (any[], function, () =&gt; boolean) -&gt;  any[]</span>

_.tillWhen = <span class="hljs-function">(<span class="hljs-params">data, fn, predicate</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (!data || !<span class="hljs-built_in">Array</span>.isArray(data)) <span class="hljs-keyword">return</span> data;
  <span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> arr = [];
  <span class="hljs-keyword">do</span> {
    arr.push(fn(data[index]));
  } <span class="hljs-keyword">while</span> (index &lt; data.length &amp;&amp; !predicate(data[index++]));
  <span class="hljs-keyword">return</span> arr;
};
<span class="hljs-built_in">module</span>.exports = _
</code></pre>
<p><strong>Uses:</strong> Using <em>tillWhen</em> is pretty much simple and straight forward.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> mapValue = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> v;
};
<span class="hljs-keyword">const</span> till5 = <span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v % <span class="hljs-number">3</span> == <span class="hljs-number">0</span>;
_.tillWhen(data, mapValue, till5)
  .forEach(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(x));
<span class="hljs-comment">// Output: 1 2 3 4 5</span>
</code></pre>
<p>Looks like we have nearly touched the surface of <strong>JavaScript's Weird Part</strong>. In the end, We have achieved what we want to achieve. If you have more suggestions. Please let me know in the comments.</p>
<p>Please do <strong>subscribe/follow/react</strong> to support me. Thanks.!! 🙏🙏</p>
<p><strong>References</strong>: </p>
<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops_and_iteration</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/2641347/short-circuit-array-foreach-like-calling-break">short-circuit-array-foreach-like-calling-break</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Optimise your Frontend CI/CD pipeline with Go and ESBuild]]></title><description><![CDATA[If you heard of the Snowpack, You may be familiar with ESBuild. ESBuild is one of the fastest bundler/compilers for the Frontend libraries. ESBuild is not a bundler for Reactjs, It can bundle any JavaScript modules. ESBuild is written in  Golang, whi...]]></description><link>https://blog.decipher.dev/optimize-your-frontend-cicd-pipeline-with-go-and-esbuild</link><guid isPermaLink="true">https://blog.decipher.dev/optimize-your-frontend-cicd-pipeline-with-go-and-esbuild</guid><category><![CDATA[Frontend Development]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Wed, 17 Mar 2021 08:29:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615720769687/DT9RLAoR9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you heard of the <a target="_blank" href="https://www.snowpack.dev/">Snowpack</a>, You may be familiar with <a target="_blank" href="https://esbuild.github.io/">ESBuild</a>. ESBuild is one of the fastest bundler/compilers for the Frontend libraries. ESBuild is not a bundler for Reactjs, It can bundle any JavaScript modules. ESBuild is written in  <a target="_blank" href="https://golang.org/">Golang</a>, which make is fast. ESBuild is not a complete solution for your all need. However, Implementing it in your pipeline significantly can improve your team productivity and deployment build time.</p>
<p><strong>Prerequisite: </strong></p>
<ol>
<li>Go [v1.6 and above]</li>
<li>NPM (nodejs package manager)</li>
</ol>
<p><strong>Note:</strong>  <a target="_blank" href="https://esbuild.github.io/getting-started/#install-esbuild">ESBuild</a>  is also available in nodejs. However, I find using Go and create binary CLI is much faster and reusable.</p>
<h2 id="why-should-i-use-esbuild-when-i-have-the-webpack">Why should  I use ESBuild when I have the webpack?</h2>
<p><em>There is no reason that you should stop using <a target="_blank" href="https://webpack.js.org/">webpack</a>. But there are a lot of reasons you can at least start thinking of using ESBuild. Some of the best ones are given below. For more info, you can visit  <a target="_blank" href="https://esbuild.github.io/faq/#why-is-esbuild-fast">the official page.</a> </em></p>
<ol>
<li>It's written in Go and compiles to <strong>native code</strong>.</li>
<li><strong>Parallelism</strong> is used heavily.</li>
<li><strong>Memory</strong> is used efficiently.</li>
<li>Loaders and plugins added by default</li>
</ol>
<p><strong>[Compilers time comparison]</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615723347496/3Z3868-a5.png" alt="Compilers time comparison" /></p>
<h2 id="where-to-start">Where to start</h2>
<p>To build a pipeline, You need an application. You can start a project from scratch as it is documented  <a target="_blank" href="https://esbuild.github.io/getting-started/#your-first-bundle">here</a>. However, For demo purpose, I will use the  <a target="_blank" href="https://github.com/deepakshrma/es-build-react">Quote of the day</a>  app that I have created in Github.</p>
<h2 id="project-structure">Project Structure</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615719935720/rluJlAeCN.png" alt="Project Structure" /></p>
<ul>
<li><strong>public: </strong>A place to keep all public file like image</li>
<li><strong>src: </strong>It contains the source code written in TypeScript and ReactJS</li>
<li><strong>package.json: </strong>This will contain all the common scripts and dependencies for the nodejs app</li>
<li><strong>runner.go: </strong>The build script is written in Golang to use ESBuild to compile and bundle typescript</li>
<li><strong>tsconfig.json:</strong> Basic configuration for a TypeScript and react project.</li>
</ul>
<p>The rest of the files and folder you can ignore for now.</p>
<p><strong>Note: </strong>The purpose of the article to show how to user ESBuild. So I am not going into the details of react app. You can find source code here in <a target="_blank" href="https://github.com/deepakshrma/es-build-react">Quote of the day</a> repo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615720230119/NMdCK3hUU.png" alt="React App Code" /></p>
<p>[Screenshot of code]</p>
<h2 id="write-your-first-go-script">Write your first Go Script</h2>
<p><strong>Open <code>runner.go</code> and add below code</strong></p>
<pre><code class="lang-go"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"os"</span>

    <span class="hljs-string">"github.com/evanw/esbuild/pkg/api"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    result := api.Build(api.BuildOptions{
        EntryPoints: []<span class="hljs-keyword">string</span>{<span class="hljs-string">"src/app.tsx"</span>},
        Outdir:      <span class="hljs-string">"dist"</span>,
        Bundle:      <span class="hljs-literal">true</span>,
        Write:       <span class="hljs-literal">true</span>,
        LogLevel:    api.LogLevelInfo,
    })
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(result.Errors) &gt; <span class="hljs-number">0</span> {
        os.Exit(<span class="hljs-number">1</span>)
    }
}
</code></pre>
<p><strong>Create go module and get all go dependencies</strong></p>
<pre><code class="lang-bash"><span class="hljs-comment">## Create/init a go module</span>
go mod init quote-of-day 

<span class="hljs-comment">## Create vendor module/directory for all dependencies(similar to **node_modules**)</span>
go mod vendor 

<span class="hljs-comment">## Get all go dependencies</span>
go mod tidy
</code></pre>
<p>Once you are done with go modules, Let's update <code>package.json</code> to build go binary runner.</p>
<pre><code class="lang-json"><span class="hljs-comment">/*package.json*/</span>

<span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"build:bin"</span>: <span class="hljs-string">"go build -o runner.exe runner.go"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"./runner.exe &amp;&amp; cp public/* dist/"</span>,
    <span class="hljs-attr">"serve"</span>: <span class="hljs-string">"http-server dist"</span>,
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
</code></pre>
<p><strong> Explanation:</strong> <code>npm run build:bin</code> will create an executable binary(runner.exe). This will we used to compile react source code. To compile react code next time you can use <code>npm run build</code>.</p>
<p><strong>Note:</strong> We can use the <code>go run</code> command directly. However, Binary will be much faster and can be distributed among the teams.</p>
<p><strong>Run Build:</strong> Once you run <code>npm run build</code>, You will see the output as below. You will see some warnings, We will fix these later. </p>
<p><em>Things to be noted, The <strong>size of</strong> the <code>app.js</code>. It will be around <code>1mb</code> which is too high for such a small app.</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615721976646/FGfuKGK5E.png" alt="Build output" /></p>
<h2 id="optimise-build-settings-and-fix-warning-messages">Optimise build settings and Fix warning messages</h2>
<p>To optimize the es build settings, Let's add below <code>BuildOptions</code> in <code>runner.go</code></p>
<pre><code class="lang-go"><span class="hljs-comment">//... rest of the code</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    result := api.Build(api.BuildOptions{
        EntryPoints:       []<span class="hljs-keyword">string</span>{<span class="hljs-string">"src/app.tsx"</span>},
        Outdir:            <span class="hljs-string">"dist"</span>,
        Bundle:            <span class="hljs-literal">true</span>,
        Write:             <span class="hljs-literal">true</span>,
        LogLevel:          api.LogLevelInfo,
        ChunkNames:        <span class="hljs-string">"chunks/[name]-[hash]"</span>,
        MinifyWhitespace:  <span class="hljs-literal">true</span>,
        MinifyIdentifiers: <span class="hljs-literal">true</span>,
        MinifySyntax:      <span class="hljs-literal">true</span>,
        Splitting:         <span class="hljs-literal">true</span>,
        Format:            api.FormatESModule,
        Color:             api.ColorAlways,
        Define: <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">string</span>{
            <span class="hljs-string">"process.env.NODE_ENV"</span>: <span class="hljs-string">`"dev"`</span>,
        },
        AssetNames: <span class="hljs-string">"assets/[name]-[hash]"</span>,
        Loader: <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]api.Loader{
            <span class="hljs-string">".png"</span>: api.LoaderFile,
        },
        Engines: []api.Engine{
            {api.EngineChrome, <span class="hljs-string">"58"</span>},
            {api.EngineFirefox, <span class="hljs-string">"57"</span>},
            {api.EngineSafari, <span class="hljs-string">"11"</span>},
            {api.EngineEdge, <span class="hljs-string">"16"</span>},
        },
    })
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(result.Errors) &gt; <span class="hljs-number">0</span> {
        os.Exit(<span class="hljs-number">1</span>)
    }
}
</code></pre>
<p><em>Now re-build runner.exe and re-run the build with <code>npm run build:bin &amp;&amp; npm run build</code> commands. This time you won't see any error or warning. Same time, The size of the app.js will be reduced to <code>283.4kb</code>.
</em></p>
<h2 id="quote-of-the-day-application">Quote Of the Day application</h2>
<p>To see the output, I have added <code>http-server</code> in the <code>devDependencies</code>. You can use any other static server.</p>
<pre><code class="lang-bash">npm run serve
</code></pre>
<p><strong>[Quote Of the Day App Demo]</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615722739316/QB420XVEZ.png" alt="App Demo" /></p>
<h2 id="comparison-with-webpack">Comparison with Webpack</h2>
<p>I tried to compare build time with Webpack with bare minimal configuration. For that we do need to add some dev dependencies and Webpack itself.</p>
<p><strong>Add dependencies:</strong> Add webpack and some loaders</p>
<pre><code class="lang-bash">npm install --save-dev css-loader style-loader webpack webpack-cli typescript ts-loader
</code></pre>
<p><strong>Update package scripts:</strong> Add new command to run build using webpack</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
    ...
    <span class="hljs-attr">"webpack"</span>: <span class="hljs-string">"webpack &amp;&amp; cp public/* dist/"</span>,
   ...
  },
</code></pre>
<p><strong>Create a webpack configuration file:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/app.tsx"</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">"production"</span>,
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.tsx?$/</span>,
        use: <span class="hljs-string">"ts-loader"</span>,
        <span class="hljs-attr">exclude</span>: <span class="hljs-regexp">/node_modules/</span>,
      },
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/i</span>,
        use: [<span class="hljs-string">"style-loader"</span>, <span class="hljs-string">"css-loader"</span>],
      },
    ],
  },
  <span class="hljs-attr">resolve</span>: {
    <span class="hljs-attr">extensions</span>: [<span class="hljs-string">".tsx"</span>, <span class="hljs-string">".ts"</span>, <span class="hljs-string">".js"</span>],
  },
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"app.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>),
  },
};
</code></pre>
<p><strong>Let's run both commands and compare:</strong></p>
<ul>
<li>Run ESBuild: npm run build</li>
<li>Run Webpack: npm run webpack</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615732767053/0WetcGh_s.gif" alt="ESBuild vs Webpack" /></p>
<p><em>The time taken by Webpack v/s ESbuild is <code>5.387s/0.329s</code>. As you can clearly see the difference between Webpack vs ESBuild time. ESBuild is 16x faster than Webpack.</em></p>
<h2 id="conclusion">Conclusion</h2>
<p>ESBuild is not one solution for all your needs. In my opinion, ESBuild should not be used for development purpose. It is not a complete tool. You may struggle to enable a feature like live reload. For that, you can use <a target="_blank" href="https://www.snowpack.dev/">Snowpack</a> which is built on top of ESBuild APIs. However, by Optimizing build configs and proper scripting pipeline, You can optimize your CI/CD pipeline significantly. </p>
<p>There is a nice quote by <strong><em>Coco Chanel</em></strong></p>
<blockquote>
<p>“To be irreplaceable, one must always be different ” – Coco Chanel</p>
</blockquote>
<p><strong>Code: </strong> You can all code in <a target="_blank" href="https://github.com/deepakshrma/es-build-react">es-build-react GitHub repo</a>. And webpack version of the code can be found in <a target="_blank" href="https://github.com/deepakshrma/es-build-react/tree/esbuild_vs_webpack">esbuild_vs_webpack branch</a> of Github repo.</p>
<hr />
<p>If you like and appreciate my hours of effort to <strong>research</strong>, <strong>write code</strong> and <strong>write this article</strong>. Please share your love and reaction ;) 😊. Thanks in advance.</p>
]]></content:encoded></item><item><title><![CDATA[Are For Loops or ForEach Better in JavaScript?]]></title><description><![CDATA[Whenever I review a code, I see people keep mixing for and forEach in their code. Either they are confused, or they can’t differentiate between for and forEach. As a thumbs rule, You should always use forEach except for a few scenarios. Here in this ...]]></description><link>https://blog.decipher.dev/are-for-loops-or-foreach-better-in-javascript</link><guid isPermaLink="true">https://blog.decipher.dev/are-for-loops-or-foreach-better-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[best practices]]></category><category><![CDATA[design patterns]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 16 Mar 2021 12:04:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615895500736/PbRbfwtDi.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Whenever I review a code, I see people keep mixing <strong>for</strong> and <strong>forEach</strong> in their code. Either they are confused, or they can’t differentiate between for and forEach. As a thumbs rule, You should always use forEach except for a few scenarios. Here in this article, I will explain when you should make those exceptions. This is valid for <code>**Array.map**</code> also.</p>
<h2 id="basic-syntax">Basic syntax</h2>
<p>Before going further let’s have a quick look at both of the syntaxes.</p>
<p><strong>For Loop:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span> ([initialExpression]; [conditionExpression];[incrementExpression]) {  
  statement|s  
}

<span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];  
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index &lt; array.length; index++) {  
  <span class="hljs-built_in">console</span>.log(array[index]);  
}
</code></pre>
<p><strong>ForEach Loop:</strong></p>
<pre><code class="lang-js">arr.forEach(callback(currentValue[, index[, array]]) {  
  <span class="hljs-comment">// execute something  </span>
}[, thisArg]);

<span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];  
array.forEach(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> {  
  <span class="hljs-built_in">console</span>.log(item);  
});
</code></pre>
<p>Here in the above samples, Both code will print the log sequence of numbers. ForEach takes a functional approach to solving the problem. ForEach takes a function callback and execute over each value in the array. The <strong>forEach</strong> method looks more concise than the <strong>For loop</strong>. But there are cases where we need for loop, or we can say for loop is better than forEach. Let’s explore.</p>
<p><strong>1. Looping to a range of values:</strong> Suppose you have to loop some code for particular times(assume 100). You can’t use forEach here. Because for ForEach you need to have an array of data. You can use <strong>Array(100).fill(0) to</strong> create an Array of data filled with 0. But it is an extra headache.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Sum of the first 99 natural numberslet sum = 0;  </span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index &lt; <span class="hljs-number">100</span>; index++) {  
  sum += index;  
}
</code></pre>
<p>Same code using forEach</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>;  
<span class="hljs-built_in">Array</span>(<span class="hljs-number">100</span>)  
  .fill(<span class="hljs-number">0</span>)  
  .forEach(<span class="hljs-function">(<span class="hljs-params">_, index</span>) =&gt;</span> {  
    sum += index;  
  });  

<span class="hljs-built_in">console</span>.log(sum); <span class="hljs-comment">// 4950</span>
</code></pre>
<p>Here the complexity of the code is high( <strong>O(2n)</strong>). Since we are looping 2 times. One to fill the array and the second one to iterate the array to collect natural numbers.</p>
<p><strong>2. Increment index other than 1:</strong> This is another good case, Where you should use for loop instead of forEach. It will reduce the complexity of the code.</p>
<p>For example, Think you have an array of data and you have to perform collect pairs of the data.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];  
<span class="hljs-keyword">let</span> pairs = [];  

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index &lt; numbers.length; index += <span class="hljs-number">2</span>) {  
  pairs.push([numbers[index], numbers[index + <span class="hljs-number">1</span>]]);  
}

<span class="hljs-built_in">console</span>.log(pairs); <span class="hljs-comment">// [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6, 7 ] ]</span>
</code></pre>
<p>Notice we can skip(increment) index by any number here. If you have to do the same using the forEach loop you have to have some logic to skip the 2nd number each time.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];  
<span class="hljs-keyword">let</span> pairs = [];

numbers.forEach(<span class="hljs-function">(<span class="hljs-params">item, index</span>) =&gt;</span> {  
  <span class="hljs-keyword">if</span> (index % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>) {  
    pairs.push([item, numbers[index + <span class="hljs-number">1</span>]]);  
  }  
});  

<span class="hljs-built_in">console</span>.log(pairs); <span class="hljs-comment">// [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6, 7 ] ]</span>
</code></pre>
<p><img alt src="https://miro.medium.com/max/4800/0*uZD58Tjp1AxyWKQv" /></p>
<p><strong>3. Conditional Break/Continue in a loop:</strong> Due to some reason If your code requires to conditional break loop. For loop is better to use than forEach. This is because breaking a forEach loop is pain. I have written an entire article just to explain <a target="_blank" href="/weird-part-how-to-break-the-loop-in-javascript-8bba3e658267">how to break a loop.</a></p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>; index &lt; numbers.length; index++) {  
  <span class="hljs-keyword">if</span> (numbers[index] &gt; <span class="hljs-number">5</span>) {  
    <span class="hljs-keyword">break</span>;  
  }  
  <span class="hljs-built_in">console</span>.log(numbers[index]); <span class="hljs-comment">// 0, 1, 2, 3, 4, 5  </span>
}
</code></pre>
<p>Similar code if you have to write using forEach, You have to throw an error and catch it.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> numbers = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>];<span class="hljs-keyword">const</span> printValueTill5 = <span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> {  
  <span class="hljs-keyword">if</span> (v % <span class="hljs-number">5</span> == <span class="hljs-number">0</span>) {  
    **<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"index is greater than 5"</span>);**  
  }  
  <span class="hljs-built_in">console</span>.log(v);  
};  
<span class="hljs-keyword">try</span> {  
  numbers.forEach(printValueTill5);  
} <span class="hljs-keyword">catch</span> {}
</code></pre>
<p><strong>4. Working in the chunks, split array:</strong> Another good use case could be when you have to work in the chunk of the data. So you can start index from where you leftover in the first iteration.</p>
<p>For example, Suppose you have to merge 2 arrays and you are not sure about the size of both arrays.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> array1 = [<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>];  
<span class="hljs-keyword">const</span> array2 = [<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>];  
<span class="hljs-keyword">const</span> merged = [];<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>;  

<span class="hljs-keyword">for</span> (; index &lt; array1.length &amp;&amp; index &lt; array2.length; index++) {  
  merged.push(array1[index]);  
  merged.push(array2[index]);  
}

<span class="hljs-comment">// loop over array1, if left any  </span>
<span class="hljs-keyword">for</span> (; index &lt; array1.length; index++) {  
  merged.push(array1[index]);  
}

<span class="hljs-comment">// loop over array2, if left any  </span>
<span class="hljs-keyword">for</span> (; index &lt; array2.length; index++) {  
  merged.push(array2[index]);  
}

<span class="hljs-built_in">console</span>.log(merged); <span class="hljs-comment">// [1,2,3,4,5,6,7,8,9,10]</span>
</code></pre>
<p>I can’t even think of writing the same code using forEach.</p>
<p><strong>5. Working with nested loop:</strong> Another challenge of a forEach loop is working with nested loops. Nesting a forEach can loop very ugly. Same time it can leads to callback hell very easily.</p>
<p>For Example, fill a 2D/3D array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> matrix = [];<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++) {  
  matrix[i] = [];  
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">3</span>; j++) {  
    matrix[i][j] = [i, j];  
  }  
}  

<span class="hljs-built_in">console</span>.log(matrix);

<span class="hljs-comment">/*  
[  
  [ [ 0, 0 ], [ 0, 1 ], [ 0, 2 ] ],  
  [ [ 1, 0 ], [ 1, 1 ], [ 1, 2 ] ],  
  [ [ 2, 0 ], [ 2, 1 ], [ 2, 2 ] ]  
]  
*/</span>
</code></pre>
<h2 id="conclusion">Conclusion</h2>
<p>Maybe working with raw for loop is tricky and error-prone. But for loop has its own place. It gives you full control over <strong>data</strong>, <strong>index</strong> and <strong>condition</strong> flow. Same time based on the above examples, We can make the assumption that whenever your work requires more interaction with the index/conditional expression. You can use for-loop. For the rest of the case use <strong>forEach</strong> for data first uses.</p>
<p><em>Thanks for appreciating my effort. It encourages me to write more and better than the previous.</em></p>
<p><strong>“I know it has been tough but I still cheering for you.”</strong> - Anonymous</p>
]]></content:encoded></item><item><title><![CDATA[How you should not write code | chapter 2 | JavaScript]]></title><description><![CDATA[Writing a JavaScript code requires less effort. However, Due to its dynamic nature. It is hard to maintain and scale. To write better code, you need to understand its pitfalls. In this article, I will cover the common misleading APIs and patterns in ...]]></description><link>https://blog.decipher.dev/how-you-should-not-write-code-javascript-2</link><guid isPermaLink="true">https://blog.decipher.dev/how-you-should-not-write-code-javascript-2</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[clean code]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 09 Mar 2021 15:15:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615468510153/pT3k6N0QW.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Writing a JavaScript code requires less effort. However, Due to its dynamic nature. It is hard to maintain and scale. To write better code, you need to understand its pitfalls. In this article, I will cover the common misleading APIs and patterns in JavaScript.</p>
<p><em>“The more I learn, the more I realize how much I don’t know.” —</em> <strong><em>Albert Einstein</em></strong></p>
<p><em>This article is a continuation of my previous article</em> <a target="_blank" href="https://blog.decipher.dev/how-you-should-not-write-code-or-javascript"><em>How you should not write code</em></a><em>. If you have not read it, I will suggest you please read it.</em></p>
<h2 id="1-requiring-begging-is-not-good"><strong>1. Requiring (Begging) is not good</strong></h2>
<p>I have seen code where reading a <code>JSON file</code>, developers use <code>[require](https://nodejs.org/api/modules.html#modules_require_id)</code>. However, <code>require</code> is not that performant as you think. Let’s explore with an example.</p>
<p>Create a <code>user.json</code> inside the folder <strong>[require_files].</strong> I am showing a small code snippet of a big JSON file. However, you can download the longer version from Github.</p>
<pre><code class="lang-json"><span class="hljs-comment">// require_files/user.json</span>
[
  {
    <span class="hljs-attr">"_id"</span>: <span class="hljs-string">"5dea8219b7e4e8016a6661e0"</span>,
    <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>,

    <span class="hljs-attr">"address"</span>: <span class="hljs-string">"231 Vandervoort Place, Hollins, South Carolina, 2782"</span>,
    <span class="hljs-attr">"about"</span>: <span class="hljs-string">"Ex nulla do duis exercitation Lorem occaecat veniam tempor voluptate laboris adipisicing proident incididunt incididunt. Aliqua enim duis quis esse eiusmod eiusmod tempor velit duis qui anim in. Ipsum incididunt occaecat eu sint. Ut nulla est commodo laborum minim incididunt proident nostrud consectetur tempor. Eiusmod aute tempor eu aute enim nulla ut aliquip. Pariatur consequat tempor tempor irure sunt cillum. Ullamco Lorem Lorem ullamco enim ex elit ut pariatur in qui.\r\n"</span>,
    <span class="hljs-attr">"greeting"</span>: <span class="hljs-string">"Hello, Cherie Webster! You have 7 unread messages."</span>,
    <span class="hljs-attr">"favoriteFruit"</span>: <span class="hljs-string">"strawberry"</span>
  }
]
</code></pre>
<p>Let’s create the main function:</p>
<pre><code class="lang-js"><span class="hljs-comment">// req.js</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE"</span>);
  <span class="hljs-keyword">const</span> user = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./user.json"</span>);
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE"</span>);
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-2"</span>);
  <span class="hljs-keyword">const</span> userJson = <span class="hljs-built_in">JSON</span>.parse(fs.readFileSync(__dirname + <span class="hljs-string">"/user.json"</span>));
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-2"</span>);
}
main();
<span class="hljs-comment">// output</span>
<span class="hljs-comment">// REQUIRE: 0.989ms</span>
<span class="hljs-comment">// REQUIRE-2: 0.245ms</span>
</code></pre>
<p>If you notice the timing of the <code>require</code> and <code>readFileSync</code>, it is drastically different. The reason, <code>require</code> the method does a lot of things behind the scenes (like <strong>caching)</strong>.</p>
<p>Let’s see another version of it inside a loop.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE"</span>);
  <span class="hljs-keyword">const</span> user = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./user.json"</span>);
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE"</span>);
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-2"</span>);
  <span class="hljs-keyword">const</span> userJson = <span class="hljs-built_in">JSON</span>.parse(fs.readFileSync(__dirname + <span class="hljs-string">"/user.json"</span>));
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-2"</span>);
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-FOR"</span>);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> e = <span class="hljs-number">0</span>; e &lt; <span class="hljs-number">10000</span>; e++) 
    <span class="hljs-built_in">require</span>(<span class="hljs-string">"./user.json"</span>);
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-FOR"</span>);
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-FOR-2"</span>);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> e = <span class="hljs-number">0</span>; e &lt; <span class="hljs-number">10000</span>; e++)
    <span class="hljs-built_in">JSON</span>.parse(fs.readFileSync(__dirname + <span class="hljs-string">"/user.json"</span>));
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-FOR-2"</span>);
}
main();
<span class="hljs-comment">// Output</span>
<span class="hljs-comment">// REQUIRE: 0.956ms</span>
<span class="hljs-comment">// REQUIRE-2: 0.190ms</span>
<span class="hljs-comment">// REQUIRE-FOR: 164.483ms</span>
<span class="hljs-comment">// REQUIRE-FOR-2: 663.703ms</span>
</code></pre>
<p>Here in <code>for-loop</code>, I have required the same file again and again. Since <code>require</code> is cached, <code>require</code> is very fast compared to our version of <code>[fs.readFileSync](https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options)</code>. Let’s create a cached <code>requireJSON</code> utility library.</p>
<p>Here you can clearly see the performance difference: <code>requireJSON</code> is 40 times faster than the <code>require</code>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// util.js</span>
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>);
<span class="hljs-keyword">let</span> files = {};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requireJSON</span>(<span class="hljs-params">path</span>) </span>{
  <span class="hljs-keyword">if</span> (!files[path]) {
    files[path] = <span class="hljs-built_in">JSON</span>.parse(fs.readFileSync(path));
  }
  <span class="hljs-keyword">return</span> files[path];
}
<span class="hljs-built_in">module</span>.exports = {
  requireJSON
};
<span class="hljs-comment">// req.js</span>
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>);
<span class="hljs-keyword">const</span> { requireJSON } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./util"</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// ...Rest of the code</span>
  <span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-FOR-NEW"</span>);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> e = <span class="hljs-number">0</span>; e &lt; <span class="hljs-number">10000</span>; e++) {
    <span class="hljs-built_in">require</span>(<span class="hljs-string">"./user.json"</span>);
  }
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-FOR-NEW"</span>);
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"REQUIRE-FOR-NEW-2"</span>);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> e = <span class="hljs-number">0</span>; e &lt; <span class="hljs-number">10000</span>; e++) {
    requireJSON(__dirname + <span class="hljs-string">"/user.json"</span>);
  }
  <span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"REQUIRE-FOR-NEW-2"</span>);
}
main();
<span class="hljs-comment">// Output</span>
<span class="hljs-comment">// REQUIRE: 0.737ms</span>
<span class="hljs-comment">// REQUIRE-2: 0.196ms</span>
<span class="hljs-comment">// REQUIRE-FOR: 170.930ms</span>
<span class="hljs-comment">// REQUIRE-FOR-2: 608.423ms</span>
<span class="hljs-comment">// REQUIRE-FOR-NEW: 147.607ms</span>
<span class="hljs-comment">// REQUIRE-FOR-NEW-2: 3.071ms</span>
</code></pre>
<p><strong>Note:</strong> It doesn’t mean we should not stop using <code>require</code>. <code>require</code> is mainly to load <code>JS</code> files. It has a lot of functionality. However, whenever you are dealing with <code>JSON(static)</code> files. I would recommend creating a small utility function or using any library.</p>
<p><strong>Code</strong>: <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/tree/master/js/require_files">https://github.com/deepakshrma/how-not-to-write-code/tree/master/js/require_files</a></p>
<p><img src="https://miro.medium.com/max/1400/0*n-87ArhzNbj4O8Eo" alt="Photo by Jose Aragones" /></p>
<h2 id="2-dont-use-sync-apis"><strong>2. Don’t use Sync APIs</strong></h2>
<p>In the above example, I talked a lot about <code>require</code>. However, you should not use any sync I/O in Node.js. It drastically reduces your app performance.</p>
<pre><code class="lang-js"><span class="hljs-comment">//util.js</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requireFile</span>(<span class="hljs-params">path</span>) </span>{
  <span class="hljs-keyword">if</span> (!files[path]) {
    files[path] = fs.readFileSync(path);
  }
  <span class="hljs-keyword">return</span> files[path];
}
<span class="hljs-comment">// sync_server.js</span>
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-keyword">const</span> {requireFile} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../require_files/util"</span>)
<span class="hljs-keyword">const</span> server = http.createServer();
server.on(<span class="hljs-string">'request'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  res.end(requireFile(__dirname+<span class="hljs-string">"/users.json"</span>));
});
server.listen(<span class="hljs-number">8080</span>);
<span class="hljs-comment">// no_sync_server.js</span>
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> server = http.createServer();
server.on(<span class="hljs-string">'request'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  fs.createReadStream(__dirname+<span class="hljs-string">"/users.json"</span>).pipe(res)
});
server.listen(<span class="hljs-number">8080</span>);
</code></pre>
<p><strong>AB Test benchmark:</strong> <code>ab -n 1000 -c 100 [http://localhost:8080/](http://localhost:8080/)</code></p>
<p><img src="https://miro.medium.com/max/1400/1*e37lU8e9bgE4K28sPIcXQA.png" alt="Image for post" /></p>
<p>Benchmark: Sync vs Stream</p>
<p><strong>Note:</strong> The sync version using the caching <code>requireFile</code> function</p>
<p>The performance of the sync file version seems better than createReadStream. However, the sync version is using cache API and <em>we can’t cache 2GB files like this</em>. Let’s remove the cache.</p>
<pre><code class="lang-js"><span class="hljs-comment">// utils.js</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">requireFileNoCache</span>(<span class="hljs-params">path</span>) </span>{
   <span class="hljs-keyword">return</span> fs.readFileSync(path);
}

<span class="hljs-comment">// js/no_sync/sync_server_no_cache.js</span>
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
<span class="hljs-keyword">const</span> {requireFileNoCache} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../require_files/util"</span>)
<span class="hljs-keyword">const</span> server = http.createServer();
server.on(<span class="hljs-string">'request'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  res.end(requireFileNoCache(__dirname+<span class="hljs-string">"/users.json"</span>));
});
server.listen(<span class="hljs-number">8080</span>);
</code></pre>
<p><img src="https://miro.medium.com/max/1400/1*rgalAkFZE7A4XaeuvWeEFA.png" alt="Image for post" /></p>
<p>Benchmark: Sync No Cache vs Sync</p>
<p>As you can see by just removing the cache, the performance has reduced 20%, and the file is very small. Think about if the file size is too big. It can really impact your server <code>**concurrency**</code>.</p>
<p><strong>Code:</strong> <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/tree/master/js/no_sync">https://github.com/deepakshrma/how-not-to-write-code/tree/master/js/no_sync</a></p>
<h2 id="3-hey-underscore-youre-doing-it-wrong">3. <strong>Hey Underscore, You’re Doing It Wrong</strong>:</h2>
<p>I really like the <a target="_blank" href="https://www.youtube.com/watch?v=m3svKOdZijA">video</a> of Brian Lonsdorf (DrBoolean). Here in this video, He explained how underscore is doing wrong. If you are really interested in functional programming I would recommend watching this talk.</p>
<p>Let’s see a small example from his talk.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">firstLetters</span>(<span class="hljs-params">words</span>) </span>{
    <span class="hljs-keyword">return</span> _.map(words, <span class="hljs-function">(<span class="hljs-params">word</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> _.first(word)
    })
}
<span class="hljs-built_in">console</span>.log(firstLetters([<span class="hljs-string">"Test"</span>, <span class="hljs-string">"Rest"</span>]))
<span class="hljs-comment">// [ "T", "R"]</span>
</code></pre>
<p>In the above example, <code>firstLetters</code> is trying to get the first character of words in an <code>Array</code>. If we use a <code>[**partial function**](https://scotch.io/tutorials/javascript-functional-programming-explained-partial-application-and-currying)</code>(curry) concept. We can reduce the code and make it more readable.</p>
<p>Let’s see my own version of <code>[**partial function**](https://scotch.io/tutorials/javascript-functional-programming-explained-partial-application-and-currying)</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> first = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str[<span class="hljs-number">0</span>];
};
<span class="hljs-keyword">const</span> map = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fun, arr</span>) </span>{
  <span class="hljs-keyword">return</span> arr.map(fun);
};
<span class="hljs-built_in">console</span>.log(first(<span class="hljs-string">"Test"</span>));
<span class="hljs-built_in">console</span>.log(map(first, [<span class="hljs-string">"Test"</span>, <span class="hljs-string">"Rest"</span>]));
<span class="hljs-comment">// ["T", "R"]</span>
</code></pre>
<p>In the above example, nothing is fancy. <code>first</code> returns the first character of the word and map just iterate.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> curry = <span class="hljs-function">(<span class="hljs-params">fn, arity = fn.length, ...args</span>) =&gt;</span>
  arity &lt;= args.length ? fn(...args) : curry.bind(<span class="hljs-literal">null</span>, fn, arity, ...args);
<span class="hljs-keyword">const</span> first = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str[<span class="hljs-number">0</span>];
};
<span class="hljs-keyword">const</span> map = curry(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fun, arr</span>) </span>{
  <span class="hljs-keyword">return</span> arr.map(fun);
});
<span class="hljs-keyword">const</span> firstLetters = map(first);
<span class="hljs-built_in">console</span>.log(firstLetters([<span class="hljs-string">"Test"</span>, <span class="hljs-string">"Rest"</span>]));
<span class="hljs-comment">// ["T", "R"]</span>
</code></pre>
<p>If you noticed, I have added just a small utility function <code>curry</code> which helps us to make any function a partial function. Using that now we can make our <code>firstLetters</code> function more readable/reusable.</p>
<p><strong>Code</strong>: <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/partial_fun.js">https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/partial_fun.js</a></p>
<h2 id="4-object-apis-are-not-functional">4. <strong>Object APIs are not functional</strong></h2>
<p>The object class APIs are not functional in nature. When I say so, we have to be aware of the facts. Let’s take a very basic example. Suppose we have an object of the <code>country code</code> and <code>name</code> where the key is code and value is the <code>name</code>. And we want to convert it into an array of <code>country objects</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> obj = {
    <span class="hljs-string">"IN"</span>: <span class="hljs-string">"India"</span>,
    <span class="hljs-string">"SG"</span>: <span class="hljs-string">"Singapore"</span>,
    <span class="hljs-string">"US"</span>: <span class="hljs-string">"United State Of America"</span>,
    <span class="hljs-string">"JP"</span>: <span class="hljs-string">"JAPAN"</span>,
    <span class="hljs-string">"UK"</span>: <span class="hljs-string">"United Kingdom"</span>
}
<span class="hljs-comment">// get all keys</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.keys(obj))
<span class="hljs-comment">// get all key-value pair entries</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.entries(obj))
<span class="hljs-comment">// get all countries array</span>
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"entries"</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.entries(obj).map(<span class="hljs-function">(<span class="hljs-params">[code, name]</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> {
        name,
        code
    }
}))
<span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"entries"</span>)
<span class="hljs-comment">// Output</span>
[ { <span class="hljs-attr">name</span>: <span class="hljs-string">'India'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'IN'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Singapore'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'SG'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United State Of America'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'US'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'JAPAN'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'JP'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United Kingdom'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'UK'</span> } ]
</code></pre>
<p>Here this example works perfectly. Things to be noted, <code>Object.entries</code> itself is a <code>for-loop</code> and after that, we call <code>map</code> function. Meaning, we are looping twice for the same thing.</p>
<pre><code class="lang-js"><span class="hljs-comment">// flatObject in array</span>
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"flatObject"</span>)
<span class="hljs-keyword">const</span> flatObject = <span class="hljs-function">(<span class="hljs-params">obj</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> array = []
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> obj) {
        array.push({<span class="hljs-attr">name</span>: obj[key], <span class="hljs-attr">code</span>: key})
    }
    <span class="hljs-keyword">return</span> array
}
<span class="hljs-built_in">console</span>.log(flatObject(obj))
<span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"flatObject"</span>)
<span class="hljs-comment">//Output:</span>
[ { <span class="hljs-attr">name</span>: <span class="hljs-string">'India'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'IN'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Singapore'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'SG'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United State Of America'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'US'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'JAPAN'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'JP'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United Kingdom'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'UK'</span> } ]
<span class="hljs-attr">flatObject</span>: <span class="hljs-number">0.415</span>ms
</code></pre>
<p>The code is the same as above but with a single time loop. The performance has increased significantly. In this solution, the conversion logic is tightly coupled within the function. Let's decouple it.</p>
<pre><code class="lang-js"><span class="hljs-comment">// flatObject in array, with mapper function</span>
<span class="hljs-built_in">console</span>.time(<span class="hljs-string">"flatObjectFn"</span>)
<span class="hljs-comment">// fun object, function -&gt; object[]</span>
<span class="hljs-keyword">const</span> flatObjectFn = <span class="hljs-function">(<span class="hljs-params">obj, fn</span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> array = []
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> obj) {
        array.push(fn(key, obj[key]))
    }
    <span class="hljs-keyword">return</span> array
}
<span class="hljs-built_in">console</span>.log(flatObjectFn(obj, <span class="hljs-function">(<span class="hljs-params">key, value</span>) =&gt;</span> ({<span class="hljs-attr">name</span>:value, <span class="hljs-attr">code</span>: key})))
<span class="hljs-built_in">console</span>.timeEnd(<span class="hljs-string">"flatObjectFn"</span>)
<span class="hljs-comment">//Output </span>
[ { <span class="hljs-attr">name</span>: <span class="hljs-string">'India'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'IN'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'Singapore'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'SG'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United State Of America'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'US'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'JAPAN'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'JP'</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'United Kingdom'</span>, <span class="hljs-attr">code</span>: <span class="hljs-string">'UK'</span> } ]
<span class="hljs-attr">flatObjectFn</span>: <span class="hljs-number">0.128</span>ms
</code></pre>
<p>This works the same as the above function. However, we have decoupled the conversion logic into a <code>**mapper**</code> function. And somehow it's more performant than the old version.</p>
<p><strong>Code:</strong> <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/object_apis.js">https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/object_apis.js</a></p>
<h2 id="5-lets-promise-you-wont-reject-me"><strong>5. Let’s Promise you won't reject me</strong></h2>
<p>I personally love the <code>[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)</code> API. However, I see people struggle a lot with promises. The biggest challenge is to work with multiple promises running in parallel.</p>
<p>Here is one common problem we can solve. Suppose we have to hit 2 different async APIs and we want to collect data from these two APIs.</p>
<p>Let’s see the solution.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> delay = <span class="hljs-function">(<span class="hljs-params">fn, wait, ...args</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(fn, wait, ...args);
<span class="hljs-keyword">const</span> resolve = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> {
    delay(r, <span class="hljs-number">1000</span>, <span class="hljs-string">"SUCCESS"</span>);
  });
};
<span class="hljs-keyword">let</span> all = <span class="hljs-built_in">Promise</span>.all([resolve(), resolve()]);
all.then(<span class="hljs-built_in">console</span>.log).catch(<span class="hljs-built_in">console</span>.error);
<span class="hljs-comment">// [ 'SUCCESS', 'SUCCESS' ]</span>
</code></pre>
<p><strong>Note:</strong> <code>deley</code> is a small utility function to simulate <code>async I/O</code>.</p>
<p>All looks good. However, there is an issue. What if one of the <code>call</code> fails??</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> delay = <span class="hljs-function">(<span class="hljs-params">fn, wait, ...args</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(fn, wait, ...args);
<span class="hljs-keyword">const</span> resolve = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> {
    delay(r, <span class="hljs-number">1000</span>, <span class="hljs-string">"SUCCESS"</span>);
  });
};
<span class="hljs-keyword">const</span> reject = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">_, r</span>) =&gt;</span> {
    delay(r, <span class="hljs-number">800</span>, <span class="hljs-string">"FAIL"</span>);
  });
};
<span class="hljs-keyword">let</span> all = <span class="hljs-built_in">Promise</span>.all([resolve(), reject()]);
all.then(<span class="hljs-built_in">console</span>.log).catch(<span class="hljs-built_in">console</span>.error);
<span class="hljs-comment">// Outputs</span>
FAIL
</code></pre>
<p>It fails all. We will not get output for the second API call.</p>
<p><strong>According to the types definition</strong>, <code>Promise.all</code> will reject if any promise is rejected<strong>.</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// Type definition</span>
<span class="hljs-comment">/**
 * Creates a Promise that is resolved with an array of results when all of the provided Promises
 * resolve, or rejected when any Promise is rejected.
 * <span class="hljs-doctag">@param </span>values An array of Promises.
 * <span class="hljs-doctag">@returns </span>A new Promise.
 */</span>
<span class="hljs-comment">//all&lt;T&gt;(values: (T | PromiseLike&lt;T&gt;)[]): Promise&lt;T[]&gt;;</span>
</code></pre>
<p>To solve this issue, we can create a very basic utility function <code>collectAll</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> collectAll = <span class="hljs-function">(<span class="hljs-params">...promises</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> results = [];
    <span class="hljs-keyword">let</span> counter = <span class="hljs-number">0</span>;
      <span class="hljs-keyword">const</span> final = <span class="hljs-function">(<span class="hljs-params">index, res</span>) =&gt;</span> {
        results[index] = res;
        counter++;
      <span class="hljs-keyword">if</span> (counter === promises.length) r(results);
    };
    promises.map(<span class="hljs-function">(<span class="hljs-params">promise, index</span>) =&gt;</span> {
      promise
        .then(final.bind(<span class="hljs-literal">null</span>, index))
        .catch(final.bind(<span class="hljs-literal">null</span>, index));
    });
  });
};
<span class="hljs-keyword">let</span> all = collectAll(resolve(), resolve());
all.then(<span class="hljs-built_in">console</span>.log)
all = collectAll(resolve(), reject());
all.then(<span class="hljs-built_in">console</span>.log)
<span class="hljs-comment">// Output</span>
[ <span class="hljs-string">'SUCCESS'</span>, <span class="hljs-string">'SUCCESS'</span> ]
[ <span class="hljs-string">'SUCCESS'</span>, <span class="hljs-string">'FAIL'</span> ]
</code></pre>
<p><strong>Code:</strong> <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/promis_merge.js">https://github.com/deepakshrma/how-not-to-write-code/blob/master/js/promis_merge.js</a></p>
<blockquote>
<p>Thanks for reading. If you like this article please let me know in the comment. and Please subscribe to my feeds for a more coding blog like this. You can find all code here in <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code">GitHub</a>.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[How you should not write code | JavaScript]]></title><description><![CDATA[There are many articles on the web on how to write better and clean code. I had emphasized the words clean and better. I think by the time all of us had adopted those concepts in day to day coding life. However, sometimes I feel that we do over-engin...]]></description><link>https://blog.decipher.dev/how-you-should-not-write-code-or-javascript</link><guid isPermaLink="true">https://blog.decipher.dev/how-you-should-not-write-code-or-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[clean code]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Sat, 06 Mar 2021 16:28:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615046616836/zoqP9fvJR.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are many articles on the web on how to write <strong><em>better and clean</em></strong> code. I had <strong><em>emphasized</em></strong> the words <code>clean and better</code>. I think by the time all of us had adopted those concepts in day to day coding life. However, sometimes I feel that we do over-engineering and copy-paste things. It is to save time. In this article, I will highlight some of the code practices/smells that we should either drop or don't follow it.</p>
<p><em>This is an article from a mini-series of How you should not write code. If you know how to write code and want to write better code. Please checkout work of genius <a target="_blank" href="https://blog.cleancoder.com/"><strong>Robert Martin.</strong></a></em></p>
<p><strong>1. Dependency Injection:</strong> I have seen many libraries that have created a dependency injection. DI makes code more readable and maintainable. However, this is not a valid case for JavaScript. JavaScript is a dynamic language. You can modify the context of the <code>object or constructor</code> on runtime.</p>
<p>Let's take the Client/Service DI example of <a target="_blank" href="https://en.wikipedia.org/wiki/Dependency_injection">Wikipedia</a>.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Service</span> </span>{
  getName() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"This is service"</span>;
  }
}
<span class="hljs-built_in">module</span>.exports = Service;
</code></pre>
<blockquote>
<p>Create a Client Class with and without DI</p>
</blockquote>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Service = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./Service"</span>);
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClientWithoutInjection</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.service = <span class="hljs-keyword">new</span> Service();
  }
  greet() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello "</span> + <span class="hljs-built_in">this</span>.service.getName();
  }
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClientWithInjection</span> </span>{
  <span class="hljs-keyword">constructor</span>(service) {
    <span class="hljs-built_in">this</span>.service = service;
  }
  greet() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.service.getName);
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello "</span> + <span class="hljs-built_in">this</span>.service.getName();
  }
}
<span class="hljs-built_in">exports</span>.ClientWithInjection = ClientWithInjection;
<span class="hljs-built_in">exports</span>.ClientWithoutInjection = ClientWithoutInjection;
</code></pre>
<p>Let’s write some unit test cases: I am using <a target="_blank" href="https://jestjs.io/">jest</a> here.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {
  ClientWithInjection,
  ClientWithoutInjection
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Client'</span>)
<span class="hljs-keyword">const</span> Service = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Service'</span>)
describe(<span class="hljs-string">'DI'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  describe(<span class="hljs-string">'Client'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    it(<span class="hljs-string">'check it'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> cw = <span class="hljs-keyword">new</span> ClientWithInjection(<span class="hljs-keyword">new</span> Service())
      <span class="hljs-keyword">const</span> co = <span class="hljs-keyword">new</span> ClientWithoutInjection()
      expect(cw.greet()).toBe(co.greet())
    });
  });
});
</code></pre>
<p>In the above test suite, I have satisfied both the class here. Nothing fancy. All the tests work fine. <code>**_cw.greet()_**</code> and <code>**_co.greet()_**</code> return the same value which is <strong>“Hello This is service”.</strong></p>
<p>Now let’s write another test file with some magic of mocking</p>
<pre><code class="lang-js">jest.mock(<span class="hljs-string">'./Service'</span>, <span class="hljs-function">() =&gt;</span> (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">this</span>.getName = <span class="hljs-function">() =&gt;</span> <span class="hljs-string">"something else"</span>
}));
<span class="hljs-keyword">const</span> {
  ClientWithoutInjection
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Client'</span>)
describe(<span class="hljs-string">'DI'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  describe(<span class="hljs-string">'Client'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    it(<span class="hljs-string">'check it'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> co = <span class="hljs-keyword">new</span> ClientWithoutInjection()
      expect(co.greet()).toBe(<span class="hljs-string">"Hello something else"</span>)
    });
  });
});
</code></pre>
<p>If you notice, I have to change the expected value in the test case. This will still work. This is because I have <code>mocked</code> the service to return <strong><em>“something else”.</em></strong> So we can stop overthinking DI at least for Javascript.</p>
<p><strong>2. Underscore(_) and $ for private variable:</strong> <code>**_/$**</code> for private variable become famous from the ages when people were coding in languages like <strong>C++, C</strong>. At that time we didn't have any coding guidelines and linting-tool to prevent bugs. And it becomes naming conventions. I have seen variable names like <strong>___name__something__new</strong>. It’s like adding more <strong>_ and</strong> the variable will become more private. By the time, things had been changed. Now we have superb IDE and plugins to support.</p>
<p>If you really care about the private variable. You can use a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol"><strong>Symbol</strong></a> with <strong>ES2015</strong> or the latest. <strong>Babel/Typescript</strong> also supports private variables. Below are a few samples to demonstrate.</p>
<blockquote>
<p>Using Symbol:</p>
</blockquote>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> property = <span class="hljs-built_in">Symbol</span>();
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Something</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>[property] = <span class="hljs-string">"test"</span>;
  }
}
<span class="hljs-keyword">var</span> instance = <span class="hljs-keyword">new</span> Something();
<span class="hljs-built_in">console</span>.log(instance[<span class="hljs-string">"property"</span>]); <span class="hljs-comment">// undefined</span>
<span class="hljs-built_in">console</span>.log(instance); <span class="hljs-comment">// Something { [Symbol()]: 'test' }</span>
</code></pre>
<blockquote>
<p>Using old-style constructor/closure:</p>
</blockquote>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
  <span class="hljs-keyword">constructor</span>(nm) {
    <span class="hljs-built_in">this</span>.setName = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">name</span>) </span>{
      nm = name;
    };
    <span class="hljs-built_in">this</span>.getName = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">return</span> nm;
    };
  }
}
<span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"deepak"</span>);
<span class="hljs-built_in">console</span>.log(person.getName()); <span class="hljs-comment">// "deepak"</span>
person.setName(<span class="hljs-string">"kapeed"</span>);
<span class="hljs-built_in">console</span>.log(person.getName()); <span class="hljs-comment">// "kapeed"</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonF</span>(<span class="hljs-params">nm</span>) </span>{
  <span class="hljs-built_in">this</span>.setName = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">name</span>) </span>{
    nm = name;
  };
  <span class="hljs-built_in">this</span>.getName = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> nm;
  };
}
<span class="hljs-keyword">const</span> personf = <span class="hljs-keyword">new</span> PersonF(<span class="hljs-string">"deepak"</span>);
<span class="hljs-built_in">console</span>.log(personf.getName()); <span class="hljs-comment">// "deepak"</span>
personf.setName(<span class="hljs-string">"kapeed"</span>);
<span class="hljs-built_in">console</span>.log(personf.getName()); <span class="hljs-comment">// "kapeed"</span>
</code></pre>
<p><strong>3. Explicitly assign null to a variable:</strong> <strong>null</strong> is not <strong>undefined</strong>, and <strong>null</strong> is not <strong>false</strong>. When I say this statement, I mean it. Many of the times when I get a code to review, often I see people assign explicitly null to a member variable, to signify that it contains <strong>no value</strong>. However, this could lead to a big issue and can become a code smell. See the below examples.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name || <span class="hljs-literal">null</span>;
  }
}
<span class="hljs-keyword">var</span> deepak = <span class="hljs-keyword">new</span> Person();
<span class="hljs-comment">// how they check</span>
<span class="hljs-keyword">if</span> (deepak.name == <span class="hljs-literal">null</span>) {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"null"</span>)
}
<span class="hljs-built_in">console</span>.log(deepak.name &amp;&amp; <span class="hljs-literal">true</span>); <span class="hljs-comment">// null</span>
deepak = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">""</span>);
<span class="hljs-built_in">console</span>.log(deepak.name &amp;&amp; <span class="hljs-literal">true</span>); <span class="hljs-comment">// null</span>
deepak = <span class="hljs-keyword">new</span> Person(<span class="hljs-literal">false</span>);
<span class="hljs-built_in">console</span>.log(deepak.name &amp;&amp; <span class="hljs-literal">true</span>); <span class="hljs-comment">// null</span>
deepak = <span class="hljs-keyword">new</span> Person(<span class="hljs-number">0</span>);
<span class="hljs-built_in">console</span>.log(deepak.name &amp;&amp; <span class="hljs-literal">true</span>); <span class="hljs-comment">// null</span>
</code></pre>
<p>A better way of writing the same code using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol">Symbol</a></p>
<pre><code class="lang-js"><span class="hljs-comment">// Better option</span>
<span class="hljs-keyword">const</span> NO_NAME = <span class="hljs-built_in">Symbol</span>();
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BetterPerson</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name || NO_NAME;
  }
  hasName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.name !== NO_NAME;
  }
}
deepak = <span class="hljs-keyword">new</span> BetterPerson(<span class="hljs-number">0</span>);
<span class="hljs-built_in">console</span>.log(deepak.hasName()); <span class="hljs-comment">// false</span>
deepak = <span class="hljs-keyword">new</span> BetterPerson(<span class="hljs-string">"deepak"</span>);
<span class="hljs-built_in">console</span>.log(deepak.hasName()); <span class="hljs-comment">// true</span>
</code></pre>
<p><img src="https://miro.medium.com/max/1400/0*k1YrnTQ7mA7VKW-D" alt="Image for post" /></p>
<p><strong>4. Basic use of iterator methods[forEach, map, reduce, etc.]:</strong> Lots of the time I have seen that people are still using traditional <strong>for</strong> loop. Maybe they want to write super-fast code or they trust themselves a lot. But using <strong>for</strong> loop of your own (using <strong>array.push</strong>) could lead to code smell. JavaScript has such good support for the array. At the same time is simple, we should leverage the power of Array methods.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Program:: remove all odds and multiply 5, so that u get all numbers divisible by 10</span>
<span class="hljs-comment">//Data set</span>
<span class="hljs-keyword">let</span> data = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];
<span class="hljs-keyword">const</span> MULTIPLIER = <span class="hljs-number">5</span>;
<span class="hljs-comment">//Data set</span>
<span class="hljs-comment">//Example 1</span>
<span class="hljs-keyword">let</span> mapped = [];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> index = <span class="hljs-number">0</span>, len = data.length; index &lt; len; index++) {
  <span class="hljs-keyword">if</span> (data[index] % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>) mapped.push(data[index] * MULTIPLIER);
}
<span class="hljs-built_in">console</span>.log(mapped);
</code></pre>
<p>With array reduce:</p>
<pre><code class="lang-js"><span class="hljs-comment">//Example 2</span>
mapped = data.reduce(<span class="hljs-function">(<span class="hljs-params">curr, next</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (next % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>) curr = [...curr, next * MULTIPLIER];
  <span class="hljs-keyword">return</span> curr;
}, []);
<span class="hljs-built_in">console</span>.log(mapped);
</code></pre>
<p>You can see in Example 1, There are too many things to take care of. In example 2, it looks complex. However, if you break down the example then it is easy to understand.</p>
<pre><code class="lang-js"><span class="hljs-comment">//Break down</span>
mapped = [];
<span class="hljs-keyword">const</span> isEven = <span class="hljs-function"><span class="hljs-params">num</span> =&gt;</span> num % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>; <span class="hljs-comment">// Function returns if even</span>
<span class="hljs-comment">// Accumulator fun to collect all even number</span>
<span class="hljs-keyword">const</span> accumulator = <span class="hljs-function">(<span class="hljs-params">records, num</span>) =&gt;</span> { 
  <span class="hljs-comment">// push the current numb at last and create new array</span>
  <span class="hljs-keyword">if</span> (isEven(num)) {
    records = [...records, num * MULTIPLIER];
  }
  <span class="hljs-keyword">return</span> records;
};
mapped = data.reduce(accumulator, []);
<span class="hljs-built_in">console</span>.log(mapped);
</code></pre>
<p><img src="https://miro.medium.com/max/1400/0*v9SLlXEcauOSIkz4" alt="Image for post" /></p>
<p><strong>5. Try-Catch Hell:</strong> Whenever you write <code>async-task</code> and you expect an <strong>error</strong>. In the case of Error/Fail, it becomes spaghetti code. It is very hard to maintain the catch block. Let’s see by example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> delay = <span class="hljs-function">() =&gt;</span>
  <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(r, <span class="hljs-number">1000</span>);
  });
<span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">url</span>) </span>{
  <span class="hljs-keyword">await</span> delay();
  <span class="hljs-keyword">if</span> (url == <span class="hljs-string">"fail"</span>) <span class="hljs-keyword">throw</span> <span class="hljs-string">"CODE_FAIL"</span>;
  <span class="hljs-keyword">if</span> (url == <span class="hljs-string">"fatal"</span>) <span class="hljs-keyword">throw</span> <span class="hljs-string">"CODE_FATAL"</span>;
  <span class="hljs-keyword">if</span> (url == <span class="hljs-string">""</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">"OK"</span>;
};
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetchData(<span class="hljs-string">"fail"</span>);
  } <span class="hljs-keyword">catch</span> (e) {
    <span class="hljs-keyword">if</span> (e == <span class="hljs-string">"CODE_FAIL"</span>) {
      <span class="hljs-comment">// Show toast message</span>
      <span class="hljs-built_in">console</span>.log(e); <span class="hljs-comment">// CODE_FAIL</span>
    }
    <span class="hljs-keyword">if</span> (e == <span class="hljs-string">"CODE_FATAL"</span>) {
      <span class="hljs-comment">// Show popup message</span>
      <span class="hljs-built_in">console</span>.log(e);
    }
  }
}
main();
</code></pre>
<p>Here all business logic of the failure is written inside the try-catch. This is ok for small code. However, you have the same logic in multiple places. Then you can simplify catching in the call <strong>.catch</strong> method and reuse function.</p>
<pre><code class="lang-js"><span class="hljs-comment">// catch function</span>
<span class="hljs-keyword">const</span> onCatchError = <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
  <span class="hljs-keyword">if</span> (e == <span class="hljs-string">"CODE_FAIL"</span>) {
    <span class="hljs-comment">// Show toast message</span>
    <span class="hljs-built_in">console</span>.log(e);
  }
  <span class="hljs-keyword">if</span> (e == <span class="hljs-string">"CODE_FATAL"</span>) {
    <span class="hljs-comment">// Show popup message</span>
    <span class="hljs-built_in">console</span>.log(e);
  }
};
<span class="hljs-keyword">const</span> onSomeOtherCatchError = <span class="hljs-function">() =&gt;</span> {};
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mainNew</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetchData(<span class="hljs-string">"fail"</span>)
      .catch(onCatchError) <span class="hljs-comment">// CODE_FAIL</span>
      .catch(onSomeOtherCatchError);
  } <span class="hljs-keyword">catch</span> (e) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Something else handle here"</span>);
  }
}
mainNew();
</code></pre>
<p><strong>6. A long path for import directory:</strong> I have seen path and directory structure nested to 5–10 levels. Once you have such a directory structure, you see long import paths. As a human being, it is hard to navigate backwards to find the correct file. However, Reverse<em>(Traversing from root to file)</em> is easy. See example:</p>
<pre><code class="lang-js"><span class="hljs-comment">// nest/nest/nest/nest/nest/nest/nest.js</span>
<span class="hljs-keyword">const</span> Service = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../../../../../dependency_injection/client/Service'</span>)<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> Service().getName())
<span class="hljs-comment">// package.json</span>
<span class="hljs-string">"scripts"</span>: {
  <span class="hljs-string">"nestWithout"</span>: <span class="hljs-string">"node nest/nest/nest/nest/nest/nest/nest.js"</span>,
  <span class="hljs-string">"test"</span>: <span class="hljs-string">"jest"</span>
},
</code></pre>
<p>The required service path is too long. If you have the privilege of Webpack, I will recommend you check <a target="_blank" href="https://webpack.js.org/configuration/resolve/">Webpack resolve.</a> Else you can apply a basic solution.</p>
<p>By default, <strong>NODE_PATH</strong> points to the global <strong>node_modules</strong> path. You can add any directory in <strong><em>$</em></strong><a target="_blank" href="https://nodejs.org/api/modules.html"><strong>_NODE_PATH_</strong></a> environment variable. Once the user adds any folder in NODE_PATH. It merges with the existing path. And you can require a file as <strong>node_module</strong> relative to the entry point.</p>
<pre><code class="lang-json"><span class="hljs-comment">// package.json</span>
<span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"nest"</span>: <span class="hljs-string">"NODE_PATH=./ node nest/nest/nest/nest/nest/nest/nest.js"</span>,
    <span class="hljs-attr">"nestWithout"</span>: <span class="hljs-string">"node nest/nest/nest/nest/nest/nest/nest.js"</span>,
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"jest"</span>
  },
</code></pre>
<pre><code class="lang-js">
<span class="hljs-comment">// nest/nest/nest/nest/nest/nest/nest.js</span>
<span class="hljs-keyword">const</span> Service2 = <span class="hljs-built_in">require</span>(<span class="hljs-string">'dependency_injection/client/Service'</span>)
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">new</span> Service2().getName())
</code></pre>
<p>I will try to add more examples in the future. All the source code can be found on <a target="_blank" href="https://github.com/deepakshrma/how-not-to-write-code/tree/master/js">GitHub</a> or <a target="_blank" href="https://gist.github.com/deepakshrma/09e4b31d80c34499a4e9ebbce4f8af66">Gist</a>. Please do let me know how you code.</p>
]]></content:encoded></item><item><title><![CDATA[I’m Not Using JavaScript Anymore | TypeScipt vs JavaScript]]></title><description><![CDATA[For the past few years, I have almost stopped writing JavaScript. You may ask why. It doesn't mean I don't like JavaScript. However, there is a better version of JavaScript, TypeScript. Yes, I have started developing all my library and application in...]]></description><link>https://blog.decipher.dev/im-not-using-javascript-anymore-or-typescipt-vs-javascript</link><guid isPermaLink="true">https://blog.decipher.dev/im-not-using-javascript-anymore-or-typescipt-vs-javascript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[programming languages]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Mon, 22 Feb 2021 04:13:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1613967069766/9RjGomUzX.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn-images-1.medium.com/max/1024/1*CTDoTk6JVfCY_Z8jJobVKw.png" alt /></p>
<p>For the past few years, I have almost stopped writing JavaScript. You may ask why. It doesn't mean I don't like JavaScript. However, there is a better version of JavaScript, <strong>TypeScript</strong>. Yes, I have started developing all my library and application in TypeScript. It includes the backend too.</p>
<p>Here in this article, I will try to answer the question of why you should use TypeScript instead of JavaScript. This article does not cover the pros and cons of JavaScript. Rather than just focus on Good Parts of TypeScript.</p>
<p><img src="https://cdn-images-1.medium.com/max/1024/1*SYNhIvhzDTqYOWZrkc0qjw.jpeg" alt /></p>
<h4 id="chapter-1-the-beginning">Chapter 1. The Beginning</h4>
<p>As you may know, Every story starts somewhere. I have worked on TypeScript long back ago. However, Sometimes I didn't like it. Sometimes, I felt, it is too hard to maintain so I skipped it. However, When I started working on <a target="_blank" href="https://angular.io/">Angular</a>. I didn't have that privilege to ignore TypeScript. All the code has been written in TypeScript. Even the examples are given in TypeScript. TypeScript was the first and last choice in Angular. So I had to level up my TypeScript knowledge.</p>
<p>My first reaction was bad. It is just me, I don't like thing when it forced on me. But as I mentioned, I didn't have a choice. Since we were working on a big library at that time. I do have to support a lot of stakeholders (developer in this case). Soon I realise, the more code grows in size. It reduces my effort to spend time explaining things. That how my first impression changed.</p>
<h4 id="chapter-2-how-and-where-to-start-with">Chapter 2. How and where to start with</h4>
<p>OK, Now I start liking TypeScript. Things were still not clear. I am one of the tech leads. I do have to create new libraries and utilities. Working on something created it easy. But building from scratch requires your understanding of that language. Although, TypeScript is JavaScript. However, the lifecycle is a bit different. Creating JavaScript requires a few other <strong>.js</strong> files and a <a target="_blank" href="https://www.npmjs.com/">node package manager(npm)</a>. Babel, If you do want to write code in the latest <a target="_blank" href="https://www.ecma-international.org/">ECMA standard</a>.</p>
<p><img src="https://cdn-images-1.medium.com/max/300/1*IkSWWPyXt7riDEdG1u0EpA.png" alt /></p>
<p>As you can see, You have one <strong>main.js</strong> which contains source code. <strong>__test__</strong> contains all the test cases and <strong>package.json</strong>, metadata to package.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// main.js</span>

<span class="hljs-keyword">const</span> greetings = <span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> \<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>\`;

module.exports = {  
 greetings,  
};

// package.json

{  
 "name": "js-module",  
 "version": "1.0.0",  
 "description": "",  
 "main": "main.js",  
 "scripts": {  
 "test": "node \_\_test\_\_/geetings.test.js"  
 },  
 "keywords": \[\],  
 "author": "xdeepakv",  
 "license": "ISC"  
}

// geetings.test.js

const assert = require("assert");  
const { greetings } = require("../");

assert.strictEqual(greetings("Deepak"), "Hello, Deepak");</span>
</code></pre>
<p>Pretty simple right. Yeah, maybe this is one of the simplest modules in this world. But TypeScript, you need some extra decorators(files) like <a target="_blank" href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html">TypeScript config</a>. You do need to setup compiler options.</p>
<p>In the beginning, the TypeScript community was new. So I struggle a lot to find the correct config. Same time lot of people were facing similar issues on S<a target="_blank" href="https://stackoverflow.com/questions/tagged/typescript">tackOverflow</a>. Basic TypeScript resources were OK. But, It was not good enough to build the library with proper CI/CD.</p>
<p><strong>Note:</strong> I explain the step-step guild to build the TypeScript module in later sections. Hold the beer for that time.</p>
<h4 id="chapter-3-what-to-build">Chapter 3. What to build</h4>
<p>After long research and discussion, We finalize the starter/scaffolding for our libraries. The next question was, What should we build using TypeScript. Only basic frontend libraries. We do have a few command-line tools, a few backend apps. How should we make a guideline to select the language(js/types)? Since we already had positive feedback from our last work. So we decided to build as much we could. We start building libraries, react components, CLI tools and even I go further. I have built some backend apps using TypeScript and GraphQL. If you want to learn more, please do check out my article <a target="_blank" href="https://deepak-v.medium.com/build-a-scalable-graphql-server-using-typescript-and-apollo-server-4c116ed1425e">build-a-scalable-graphql-server-using-TypeScript</a>.</p>
<h4 id="chapter-4-why-to-use-typescript">Chapter 4. Why to use TypeScript</h4>
<p>The bad parts in JavaScript are solved in TypeScript it becomes good parts of it. Just kidding. TypeScript does not try to solve the bad part of JavaScript. However, It tries to minimise the mistake/blunder causes by those bad parts. In another sense, It compliments the JS bad parts by providing better support.</p>
<h4 id="chapter-5-the-good-parts-of-typescript">Chapter 5. The Good Parts of TypeScript</h4>
<ol>
<li><strong>Start a new project config:</strong> TypeScript has <a target="_blank" href="https://www.typescriptlang.org/download">CLI</a> to create a new config in a project. <code>tsc --init</code></li>
<li><strong>Support all the browser and ECMA standard:</strong> TypeScript <a target="_blank" href="https://www.typescriptlang.org/tsconfig#compilerOptions">compiler option</a> you can provide the target ECMA standard.</li>
<li><strong>Define the source folder(Inclusion):</strong> Since working on node.js, Everything is “.js”. The biggest challenge was to separate the source code from the rest of the script. TypeScript config makes it very simple. It also supports include and exclude options. Same time with the support of <a target="_blank" href="https://www.typescriptlang.org/tsconfig#paths"><strong>paths</strong></a>, You don't have to write long import statements.</li>
<li><strong>Support for Strict rule:</strong> Before using TypeScript, I had to use <a target="_blank" href="https://eslint.org/"><strong>eslint</strong></a> and another linter module to enable some basic rule like avoid nulls. However, TypeScript does support such basic rules. There are plenty of such <a target="_blank" href="https://www.typescriptlang.org/tsconfig#alwaysStrict">rules</a> that can be used. If you are looking for more hold on rules. You may want to check <a target="_blank" href="https://palantir.github.io/tslint/">tslint</a>. It also supports to import rule from some standard libraries.</li>
<li><strong>Backward compatibility:</strong> TypeScript is backed by Microsoft. And its community is very strong. They do frequent release, the same time they do have better backward compatibility. Now, The transition from one version to another is very smooth(that was not the same when I was using TypeScript 2).</li>
<li><strong>JavaScript Support:</strong> If you are using TypeScript, It doesn't mean you can't use JavaScript. Anyhow, TypeScript is a superset of JS. TypeScript does support JavaScript. You just need to enable <strong>allowJS</strong> flag in tsconfig.</li>
<li><strong>Superset of JavaScript:</strong> This was the biggest key points for me, that I started using TypeScript. TypeScript always ahead and align to ECMA standard. When ECMA standard releases new specs. It is added in TypeScript way before it implemented in the browser. For those who don't know about ECMA standard. Please read <a target="_blank" href="https://en.wikipedia.org/wiki/ECMAScript">this</a> wiki.</li>
</ol>
<p><strong>Examples:</strong></p>
<ul>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/classes.html">Class</a></li>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers">Public, private, and protected modifiers</a></li>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/enums.html">Enum</a></li>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/basic-types.html#string">String templates</a></li>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-7.html#asyncawait-support-in-es6-targets-node-v4">async/</a><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-7.html#asyncawait-support-in-es6-targets-node-v4">await support in ES6 targets (Node v4+)</a></li>
<li><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#async-iteration">Generators</a>/Async Iterators ts 2.3</li>
<li>ES6 Import</li>
</ul>
<p>To read more on changes/features introduce to TypeScript, Read <a target="_blank" href="https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes">this</a>.</p>
<h4 id="chapter-6-happy-endingcontinuedtakeaways">Chapter 6. Happy Ending/Continued…Takeaways</h4>
<p>Like every other story, This journey has its own ending. Till now, I am happy with the uses of TypeScript. But It doesn't mean, I had stopped here. I started looking some another language like Deno and explore the options. However, the community is still young and it will take time to grow. But It seems promising. It will go longer that is my belief.</p>
<p><img src="https://cdn-images-1.medium.com/max/1024/0*NPFa7ZDBpjXtE0Sx" alt /></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@alx_andru?utm_source=medium&amp;utm_medium=referral">Alex</a> on <a target="_blank" href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></p>
<h4 id="how-to-create-a-script-module">How to create a script module</h4>
<p>As I promise, I will tell you step by step how to create a TypeScript module. Here are the steps, you can take to convert the above create JavaScript module to TypeScript.</p>
<p><strong>1. Add TypeScript</strong>: <code>npm i — save-dev typescript</code></p>
<p><strong>2. Init TypeScript config:</strong> <code>npx tsc --init</code></p>
<p><strong>3. Update folder structure:</strong></p>
<p><img src="https://cdn-images-1.medium.com/max/300/1*5WoeyCScQ_-B9sR7v51LLQ.png" alt /></p>
<p><strong>4. Update basic config to tsconfig.json:</strong></p>
<pre><code class="lang-typescript">{  
 <span class="hljs-string">"compilerOptions"</span>: {  
 <span class="hljs-string">"target"</span>: <span class="hljs-string">"es5"</span>,  
 <span class="hljs-string">"module"</span>: <span class="hljs-string">"commonjs"</span>,  
 <span class="hljs-string">"strict"</span>: <span class="hljs-literal">true</span>,  
 <span class="hljs-string">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,  
 <span class="hljs-string">"rootDir"</span>: <span class="hljs-string">"./src"</span>,  <span class="hljs-comment">/* define src directory*/</span>
 <span class="hljs-string">"outDir"</span>: <span class="hljs-string">"./lib"</span> <span class="hljs-comment">/* define js output directory*/</span>
 }  
}
</code></pre>
<p><strong>5. Add build script in <em>package.json</em> and <em>main.ts</em>:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-comment">// main.ts</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> greetings = <span class="hljs-function">(<span class="hljs-params">name: <span class="hljs-built_in">string</span></span>) =&gt;</span> \<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>\`;

// package.json

{  
 "name": "js-module",  
 "version": "1.0.0",  
 "description": "",  
 "main": "lib/main.js",
 "scripts": {  
 "build": "tsc",  
 "test": "node \_\_test\_\_/geetings.test.js"  
 },  
/// rest of the code.

}</span>
</code></pre>
<p>You have created a basic TypeScript library. To create an advance module, I will recommend using <a target="_blank" href="https://github.com/formium/tsdx">tsdx: Zero config CLI</a>.</p>
<p>Thanks, I hope you liked this article. Please thumbs up for support and care. Cheers!</p>
<p><img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=6851c707b3d1" alt /></p>
<hr />
<p><a target="_blank" href="https://js.plainenglish.io/im-not-using-javascript-anymore-6851c707b3d1">I’m Not Using JavaScript Anymore</a> was originally published in <a target="_blank" href="https://js.plainenglish.io">JavaScript in Plain English</a> on Medium.</p>
]]></content:encoded></item><item><title><![CDATA[Build a GraphQL Server using Deno(From Scratch) | Deno Advanced]]></title><description><![CDATA[Introduction
GraphQL is already known for its good parts. GraphQL helps to build super scalable APIs. It reduces coupling between code and data provider. Deno is one of the fastest-growing frameworks/languages to build APIs. However, Deno community s...]]></description><link>https://blog.decipher.dev/build-a-graphql-server-using-deno</link><guid isPermaLink="true">https://blog.decipher.dev/build-a-graphql-server-using-deno</guid><category><![CDATA[Devops]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[programming languages]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[GraphQL]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Sun, 14 Feb 2021 07:19:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1613287088435/vbomsIEhV.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>GraphQL is already known for its good parts. GraphQL helps to build super scalable APIs. It reduces coupling between code and data provider. Deno is one of the fastest-growing frameworks/languages to build APIs. However, Deno community still new. So there is a very little framework in the Deno community. Some of them are in a very early stage of development.</p>
<p>In this article, I will explain how you can easily integrate the GraphQL nodejs module with Deno lang. This is a very basic implementation. However, Still, there is a lot of scope for improvements. This is not the end. This is just beginning.</p>
<h2 id="prerequisite">Prerequisite</h2>
<ul>
<li>Deno <a target="_blank" href="https://deno.land/#installation">installed</a> on system</li>
<li>Basic knowledge of Deno <a target="_blank" href="https://decipher.dev/deno-by-example/01-hello-world">read more..</a></li>
<li>Basic understanding of routing <a target="_blank" href="https://decipher.dev/deno-by-example/advanced-routing">read more..</a></li>
<li>Basic knowledge of GraphQL <a target="_blank" href="https://deepak-v.medium.com/build-a-scalable-graphql-server-using-typescript-and-apollo-server-4c116ed1425e">read more..</a></li>
</ul>
<h2 id="steps">Steps</h2>
<h3 id="1-basic-project-directory-setup">1. Basic project directory setup</h3>
<p>First, create folders and file as described below.</p>
<p><img src="https://raw.githubusercontent.com/deepakshrma/deno-by-example/master/static/img/deno_gql_1.png" alt="sample 1" /></p>
<pre><code class="lang-bash">mkdir  src
mkdir  src/model src/resolvers src/routes src/schema
touch README.md scripts.yaml src/server.ts

<span class="hljs-comment">## Optional</span>
mkdir .vscode
touch .vscode/settings.json
</code></pre>
<p>Here, <strong>src</strong> will be the directory containing all code. <strong>model</strong> is to hold all the <em>database/models</em>. We will create all resolvers in <strong>resolvers</strong> directory. Similarly, routes and schema to keep routes and schemas respectively. <strong>src/server.ts</strong> will be an entry for the server to start with.</p>
<h3 id="2-velociraptor-as-script-runner">2. Velociraptor as script runner</h3>
<p>Deno does not have a task runner like <strong>npm</strong>. However, in Deno community, There are lots of modules we can use. I like <a target="_blank" href="https://deno.land/x/velociraptor@1.0.0-beta.16">Velociraptor</a>. It is easy to start with an easy to integrate.</p>
<pre><code class="lang-bash"><span class="hljs-comment">## You can check the current version.</span>
deno install -qA -n vr https://deno.land/x/velociraptor@1.0.0-beta.16/cli.tscl
</code></pre>
<p>Once you install velociraptor using deno, It will be available as executable as <strong>vr</strong>. You can try to validate using <code>vr --version</code>. It will print the current version of the velociraptor.</p>
<p>Let's add basic scripts in <strong>src/server.ts</strong></p>
<pre><code class="lang-yaml"><span class="hljs-attr">allow:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">net</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">read</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">env</span>

<span class="hljs-attr">scripts:</span>
  <span class="hljs-attr">start:</span>
    <span class="hljs-attr">cmd:</span> <span class="hljs-string">deno</span> <span class="hljs-string">run</span> <span class="hljs-string">src/server.ts</span>
  <span class="hljs-attr">test:</span> <span class="hljs-string">"echo 'No Test Found'"</span>
  <span class="hljs-attr">build:</span> <span class="hljs-string">deno</span> <span class="hljs-string">compile</span> <span class="hljs-string">--unstable</span> <span class="hljs-string">--allow-read</span> <span class="hljs-string">--allow-net</span> <span class="hljs-string">src/server.ts</span>
</code></pre>
<p><strong>Tips:</strong>
<strong>velociraptor</strong> supports JSON, yaml and many more formats. I like yaml version cool so I am using it.</p>
<p><strong>Explained:</strong></p>
<ul>
<li><strong>allow</strong> to allow net, read, and env permission to Deno executable</li>
<li><strong>scripts</strong> to add command.</li>
</ul>
<p>Let's add basic <strong>hello world</strong> sever in <strong>server.ts</strong></p>
<h3 id="3-basic-server-using-oakhttpsoakservergithubiooak">3. Basic server using <a target="_blank" href="https://oakserver.github.io/oak/">Oak</a></h3>
<p>We are going to use Oak to build our backend server. It is the most stable and community supported module out there.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/server.ts</span>

<span class="hljs-keyword">import</span> { Application } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak/mod.ts"</span>;
<span class="hljs-keyword">import</span> { config } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/dotenv/mod.ts"</span>;
<span class="hljs-keyword">import</span> { Logger, LoggerOptions } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/deno_util/logger.ts"</span>;

<span class="hljs-keyword">const</span> initialOptions = { level: <span class="hljs-number">0</span>, format: <span class="hljs-string">"%s"</span>, newLine: <span class="hljs-literal">true</span> };
<span class="hljs-keyword">const</span> logger = <span class="hljs-keyword">new</span> Logger(initialOptions <span class="hljs-keyword">as</span> LoggerOptions);
<span class="hljs-keyword">const</span> { PORT = <span class="hljs-number">4000</span> } = config({ safe: <span class="hljs-literal">true</span> });

<span class="hljs-keyword">const</span> app = <span class="hljs-keyword">new</span> Application();
app.use(<span class="hljs-function">(<span class="hljs-params">cxt</span>) =&gt;</span> {
  cxt.response.body = <span class="hljs-string">"Hello GraphQL"</span>;
});

logger.line(<span class="hljs-string">`🚀 Server is running on http://localhost:<span class="hljs-subst">${PORT}</span>/graphql`</span>);
<span class="hljs-keyword">await</span> app.listen({ port: <span class="hljs-built_in">Number</span>(PORT) });
</code></pre>
<p><strong>Run:</strong></p>
<pre><code class="lang-bash">vr start
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">==========================================================
||      🚀 Server is running on http://localhost:4000/graphql
==========================================================
</code></pre>
<p><strong>Info:</strong></p>
<p>You may get a pop-up to allow network access to Deno when you try to run the server.</p>
<p><strong>Explained:</strong></p>
<ul>
<li>Import oak module to create an Application.</li>
<li><a target="_blank" href="https://deno.land/x/dotenv@v2.0.0">dotevn</a> to allow create environmental variable.</li>
<li><a target="_blank" href="https://deno.land/x/deno_util@v0.0.3">deno_util</a> to create a basic logger.</li>
<li><strong>app.use</strong> to create basic route. Currently, It will respond <strong>Hello GraphQL</strong> to every request.</li>
</ul>
<h3 id="4-basic-mock-database">4. Basic mock database</h3>
<p>Since the purpose of this tutorial is not to teach you how to bind database and all. So we will mock the database as close as a real app.</p>
<p>Create a <strong>database.ts</strong> file <code>touch src/model/database.ts</code></p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/model/database.ts</span>

<span class="hljs-keyword">const</span> users = [
  {
    _id: <span class="hljs-string">"6027d46771b8a91a27bc9e13"</span>,
    index: <span class="hljs-number">0</span>,
    guid: <span class="hljs-string">"b0b80419-58a5-42ac-b488-b7c87a66f9f7"</span>,
    isActive: <span class="hljs-literal">true</span>,
    balance: <span class="hljs-string">"$3,095.41"</span>,
    picture: <span class="hljs-string">"http://placehold.it/32x32"</span>,
    age: <span class="hljs-number">26</span>,
    name: <span class="hljs-string">"Hickman Beach"</span>,
    gender: <span class="hljs-string">"male"</span>,
    email: <span class="hljs-string">"hickmanbeach@vidto.com"</span>,
    phone: <span class="hljs-string">"+1 (980) 401-2407"</span>,
    address: <span class="hljs-string">"489 Canda Avenue, Buxton, Tennessee, 252"</span>,
    about: <span class="hljs-string">"lorem.."</span>,
    registered: <span class="hljs-string">"2020-11-16T10:40:17 -08:00"</span>,
    friends: [
      {
        id: <span class="hljs-number">0</span>,
        name: <span class="hljs-string">"Franklin Gentry"</span>,
      },
    ],
  },
];

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Friend {
  id: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> User {
  _id: <span class="hljs-built_in">string</span>;
  index: <span class="hljs-built_in">number</span>;
  guid: <span class="hljs-built_in">string</span>;
  isActive: <span class="hljs-built_in">boolean</span>;
  balance: <span class="hljs-built_in">string</span>;
  picture: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
  gender: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
  phone: <span class="hljs-built_in">string</span>;
  address: <span class="hljs-built_in">string</span>;
  about: <span class="hljs-built_in">string</span>;
  registered: <span class="hljs-built_in">string</span>;
  friends: Friend[];
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getUsers = <span class="hljs-keyword">async</span> (predicate?: <span class="hljs-function">(<span class="hljs-params">user: User</span>) =&gt;</span> <span class="hljs-built_in">boolean</span>) =&gt; {
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> predicate === <span class="hljs-string">"function"</span>) <span class="hljs-keyword">return</span> users.filter(predicate);
  <span class="hljs-keyword">return</span> users;
};
</code></pre>
<p><strong>Note:</strong> You can get the whole file in <a target="_blank" href="https://github.com/deepakshrma/deno-graphql-starter">github repo</a>.</p>
<p><strong>Explained:</strong></p>
<p>A very basic mock database with <strong>getUsers</strong> method, which returns users based on a predicate. If there is no predicate, It will return all users else apply a filter using a predicate.</p>
<h3 id="5-create-a-graphql-endpoint-to-handle-graphql-post-request">5. Create a /graphql endpoint to handle graphql POST request</h3>
<p>GraphQL specs support POST to query server. We will use the same. To create a scalable routing. We will create our route in the routes folder and append it in Oak Application using the callback function.</p>
<p>Create files <code>touch src/routes/index.ts src/routes/graphql.ts</code></p>
<p>Let's create gqlrouter</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/routes/graphql.ts</span>

<span class="hljs-keyword">import</span> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak/mod.ts"</span>;

<span class="hljs-keyword">const</span> gqlrouter = <span class="hljs-keyword">new</span> Router();
gqlrouter
  .get(<span class="hljs-string">"/graphql"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-string">"Please use Post to Query"</span>;
  })
  .post(<span class="hljs-string">"/graphql"</span>, <span class="hljs-keyword">async</span> (context) =&gt; {
    <span class="hljs-keyword">const</span> result = context.request.body();
    <span class="hljs-keyword">if</span> (result.type === <span class="hljs-string">"json"</span>) {
      <span class="hljs-keyword">const</span> { query, variables = {} } = <span class="hljs-keyword">await</span> result.value;
      <span class="hljs-keyword">if</span> (query) {
        context.response.body = { query, variables };
      } <span class="hljs-keyword">else</span> {
        context.response.body = { message: <span class="hljs-string">"Invalid Query"</span> };
        context.response.status = <span class="hljs-number">400</span>;
      }
    }
  });

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> gqlrouter;
</code></pre>
<p>Let's update <strong>index.ts</strong> to append routes to Server.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/routes/index.ts</span>

<span class="hljs-keyword">import</span> {
  Application,
  Middleware,
  Router,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak/mod.ts"</span>;
<span class="hljs-keyword">import</span> { requestTraceMiddleware } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak_middlewares/mod.ts"</span>;
<span class="hljs-keyword">import</span> gqlrouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./graphql.ts"</span>;
<span class="hljs-keyword">const</span> baseRoute = <span class="hljs-keyword">new</span> Router();

baseRoute.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
  context.response.body = <span class="hljs-string">`&lt;b&gt;Please use &lt;a href="/graphql"&gt;/graphql&lt;/a&gt; to query&lt;/b&gt;`</span>;
  context.response.headers.append(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"text/html; charset=UTF-8"</span>);
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">init</span>(<span class="hljs-params">app: Application</span>) </span>{
  app.use(
    requestTraceMiddleware&lt;Middleware&gt;({ <span class="hljs-keyword">type</span>: <span class="hljs-string">"combined"</span> })
  );
  app.use(baseRoute.routes());
  app.use(gqlrouter.routes());
  app.use(gqlrouter.allowedMethods());
}
</code></pre>
<p><strong>Explained:</strong></p>
<ul>
<li><strong>graphql.ts</strong>, We have just created an instance of Oak route. It can accept a get request and a post request at endpoint "/graphql".</li>
<li>All the GraphQL request contains <strong>query</strong> and <strong>variables</strong> as data payload.</li>
<li>Currently, return <code>query and variables</code> in return response.</li>
<li><strong>index.ts</strong> to combine routes and apply some other middleware to Oak Application.</li>
</ul>
<p>Let's update our <strong>server.ts</strong></p>
<pre><code class="lang-typescript"><span class="hljs-comment">//src/server.ts</span>

<span class="hljs-comment">/// Rest of the code...</span>
<span class="hljs-keyword">import</span> init <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/index.ts"</span>;

<span class="hljs-keyword">const</span> app = <span class="hljs-keyword">new</span> Application();
init(app);

<span class="hljs-comment">/// Rest of the code...</span>
</code></pre>
<p><strong>Run:</strong>
<code>vr run start</code></p>
<p><strong>Query using Postman:</strong></p>
<p><img src="https://raw.githubusercontent.com/deepakshrma/deno-by-example/master/static/img/deno_gql_2.png" alt="sample 2" /></p>
<p><strong>Query using CURL:</strong></p>
<pre><code class="lang-bash">curl --location --request POST <span class="hljs-string">'http://localhost:4000/graphql'</span> \
--header <span class="hljs-string">'Content-Type: application/json'</span> \
--data-raw <span class="hljs-string">'{"query":"query HelloWorld {\n    hello {\n        name\n    }\n}","variables":{"name":"Hickman"}}'</span>
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"query"</span>: <span class="hljs-string">"query HelloWorld {\n    hello {\n        name\n    }\n}"</span>,
  <span class="hljs-attr">"variables"</span>: {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Hickman"</span>
  }
}
</code></pre>
<h3 id="6-create-graphql-schema-and-resolver">6. Create GraphQL schema and resolver</h3>
<p>GraphQL Executor requires schema and resolver to execute the query. For that, we need to create schema and resolver. Schema can be written in String and compile to code using <strong>buildSchema</strong> helper method. Resolvers are basic functions, will be called by graphql executor, and act on the query.</p>
<p>To use GraphQL Executor we have to install/use <a target="_blank" href="https://cdn.skypack.dev/graphql">graphql module</a> from <a target="_blank" href="https://cdn.skypack.dev/graphql">cdn.skypack.dev</a></p>
<pre><code class="lang-typescript"><span class="hljs-comment">//src/schema/user.ts</span>

<span class="hljs-keyword">const</span> UserSchema = <span class="hljs-string">`
  type Friends {
    id: Int
    name: String
  }

  type User {
    _id: String
    index: Int
    guid: String
    isActive: Boolean
    balance: String
    picture: String
    age: Int
    name: String
    gender: String
    email: String
    phone: String
    address: String
    about: String
    registered: String
    friends: [Friends]
  }
`</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> UserSchema;
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">//src/schema/index.ts</span>

<span class="hljs-keyword">import</span> { buildSchema } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://cdn.skypack.dev/graphql"</span>;
<span class="hljs-keyword">import</span> UserSchema <span class="hljs-keyword">from</span> <span class="hljs-string">"./user.ts"</span>;
<span class="hljs-keyword">const</span> base = <span class="hljs-string">`
type Query {
  hello: String
  users(name: String): [User]
}
`</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> buildSchema([base, UserSchema].join(<span class="hljs-string">"\n"</span>), {});
</code></pre>
<p><strong>Explained:</strong></p>
<ul>
<li>You can use <a target="_blank" href="https://transform.tools/json-to-graphql">json-to-graphql</a>, To generate graphql schema</li>
<li><a target="_blank" href="https://graphql.org/graphql-js/">buildSchema</a> compile and validate schema to generate code in runtime.</li>
</ul>
<p><strong>Note:</strong>  Currently, graphql does not support multi-file schema(Query). So we have to write all queries in <strong>index.ts</strong>. Hopefully, In future, we can use <a target="_blank" href="https://github.com/ardatan/graphql-tools">graphql tools</a>.</p>
<p>Let's create resolvers for <strong>users</strong> and <strong>hello</strong> query</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/resolvers/hello_world.ts</span>

<span class="hljs-keyword">const</span> HelloResolver = {
  Query: {
    hello: <span class="hljs-keyword">async</span> (_: <span class="hljs-built_in">any</span>, { name }: <span class="hljs-built_in">any</span> = {}, context: <span class="hljs-built_in">any</span>, z: <span class="hljs-built_in">any</span>) =&gt; {
      <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello world!"</span>;
    },
  },
};
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> HelloResolver;
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/resolvers/user.ts</span>

<span class="hljs-keyword">import</span> { getUsers } <span class="hljs-keyword">from</span> <span class="hljs-string">"../model/database.ts"</span>;

<span class="hljs-keyword">const</span> UserResolver = {
  Query: {
    users: <span class="hljs-keyword">async</span> (d: <span class="hljs-built_in">any</span> = {}, context: <span class="hljs-built_in">any</span>) =&gt; {
      <span class="hljs-keyword">return</span> getUsers(d.name ? <span class="hljs-function">(<span class="hljs-params">u: <span class="hljs-built_in">any</span></span>) =&gt;</span> u.name.includes(d.name) : <span class="hljs-literal">undefined</span>);
    },
  },
};
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> UserResolver;
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">//  src/resolvers/index.ts</span>

<span class="hljs-keyword">import</span> HelloResolver <span class="hljs-keyword">from</span> <span class="hljs-string">"./hello_world.ts"</span>;
<span class="hljs-keyword">import</span> UserResolver <span class="hljs-keyword">from</span> <span class="hljs-string">"./user.ts"</span>;

<span class="hljs-keyword">const</span> resolvers = <span class="hljs-built_in">Object</span>.assign(
  {},
  ...[HelloResolver, UserResolver].map(<span class="hljs-function">(<span class="hljs-params">x</span>) =&gt;</span> x.Query)
);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> resolvers;
</code></pre>
<p><strong>Explained:</strong></p>
<ul>
<li><strong>user.ts</strong> and <strong>hello.ts</strong> contains an object with Query in it. The query has the function same name as it is defined in GraphQL Schema.</li>
<li><strong>index.ts</strong> accumulate all the resolvers.</li>
</ul>
<h3 id="7-route-to-handle-query-and-execute">7. Route to handle Query and execute</h3>
<p>Now we have created schema and resolver function. We can handle GraphQL requests and responses to the query. For that, we need to update our <strong>src/routes/graphql.ts</strong>.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/routes/graphql.ts</span>

<span class="hljs-keyword">import</span> { Router } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak/mod.ts"</span>;
<span class="hljs-keyword">import</span> { graphql } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://cdn.skypack.dev/graphql"</span>;
<span class="hljs-keyword">import</span> schema <span class="hljs-keyword">from</span> <span class="hljs-string">"../schema/index.ts"</span>;
<span class="hljs-keyword">import</span> resolvers <span class="hljs-keyword">from</span> <span class="hljs-string">"../resolvers/index.ts"</span>;

<span class="hljs-keyword">const</span> gqlrouter = <span class="hljs-keyword">new</span> Router();
gqlrouter
  .get(<span class="hljs-string">"/graphql"</span>, <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> {
    context.response.body = <span class="hljs-string">"Please use Post to Query"</span>;
  })
  .post(<span class="hljs-string">"/graphql"</span>, <span class="hljs-keyword">async</span> (context) =&gt; {
    <span class="hljs-keyword">const</span> result = context.request.body();
    <span class="hljs-keyword">if</span> (result.type === <span class="hljs-string">"json"</span>) {
      <span class="hljs-keyword">const</span> { query, variables = {} } = <span class="hljs-keyword">await</span> result.value;
      <span class="hljs-keyword">if</span> (query) {
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> (graphql <span class="hljs-keyword">as</span> <span class="hljs-built_in">any</span>)(
          schema,
          query,
          resolvers,
          {
            request: context.request,
            response: context.response,
          },
          variables || {}
        );
        <span class="hljs-keyword">if</span> (data.errors) {
          context.response.body = data;
          context.response.status = <span class="hljs-number">400</span>;
        } <span class="hljs-keyword">else</span> {
          context.response.body = data;
        }
      } <span class="hljs-keyword">else</span> {
        context.response.body = { message: <span class="hljs-string">"Invalid Query"</span> };
        context.response.status = <span class="hljs-number">400</span>;
      }
    }
  });

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> gqlrouter;
</code></pre>
<p><strong>Query using Postman:</strong></p>
<p><img src="https://raw.githubusercontent.com/deepakshrma/deno-by-example/master/static/img/deno_gql_3.png" alt="sample 2" /></p>
<p><strong>Query using CURL:</strong></p>
<pre><code class="lang-bash">curl --location --request POST <span class="hljs-string">'http://localhost:4000/graphql'</span> \
--header <span class="hljs-string">'Content-Type: application/json'</span> \
--data-raw <span class="hljs-string">'{"query":"query User($name: String){\n    users(name: $name) {\n        name\n        age\n    }\n}","variables":{"name":"Hickman"}}'</span>
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"users"</span>: [
      {
        <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Hickman Beach"</span>,
        <span class="hljs-attr">"age"</span>: <span class="hljs-number">26</span>
      }
    ]
  }
}
</code></pre>
<p>Congrats, Your GraphQL Server is ready to serve(🚀) the request.</p>
<h2 id="limitations">Limitations</h2>
<p>As I mentioned earlier, Deno is still very new and the community is also very new. The above app has a lot of limitations. However, We shouldn't stop exploring it. Some of the limitations are highlighted below.</p>
<ul>
<li>Support for <a target="_blank" href="https://graphql.org/learn/queries/#aliases">multiple Query/Aliases</a></li>
<li>Merge Schema from multiple files</li>
<li>Conflict in resolvers</li>
<li>Validations and Proper Error Handling</li>
</ul>
<h2 id="source-code">Source Code</h2>
<p><a target="_blank" href="https://github.com/deepakshrma/deno-graphql-starter">deno-graphql-starter</a></p>
<p><em>I hope you like this tutorial. let me know your feedback in the comment. Please support(🙏🙏) by subscribing and clapping on <a target="_blank" href="https://deepak-v.medium.com/">https://deepak-v.medium.com/</a>.</em></p>
<p><a target="_blank" href="https://decipher.dev/deno-by-example/advanced-graphql">Find More...</a></p>
]]></content:encoded></item><item><title><![CDATA[React lazy image loading and TypeScript — No more slow and broken images]]></title><description><![CDATA[Creating a better UX is not as simple as it looks. Every component on-page matters. While working on a complex piece of code, we almost forgot about the simplest thing, a broken image.
Here in this tutorial, I will explain how you can create a simple...]]></description><link>https://blog.decipher.dev/lazy-load-image-react-typescript</link><guid isPermaLink="true">https://blog.decipher.dev/lazy-load-image-react-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[components]]></category><category><![CDATA[UX]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Thu, 15 Oct 2020 13:32:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602768718158/pvXURsvML.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Creating a <strong>better UX</strong> is not as simple as it looks. Every component on-page matters. While working on a complex piece of code, we almost forgot about the simplest thing, a broken image.</p>
<p>Here in this tutorial, I will explain how you can create a simple Image component without breaking existing code. This component will support lazy loading and broken images.</p>
<p><img src="https://images.unsplash.com/photo-1472289065668-ce650ac443d2?ixlib=rb-1.2.1&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;auto=format&amp;fit=crop&amp;w=600&amp;q=80" alt="brand" />
Photo by ©Joanna Kosinska</p>
<h3 id="1-create-an-image-component">1. Create an Image Component</h3>
<p>To start with, First Create a folder in your component library and Create a file named <code>index.tsx</code>. </p>
<pre><code class="lang-bash">mkdir -p components/Image
touch components/Image/index.tsx
</code></pre>
<p>Add below line to <code>index.tsx</code>. </p>
<pre><code class="lang-jsx"><span class="hljs-comment">// components/Image/index.tsx</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
interface ImageProps <span class="hljs-keyword">extends</span> React.ImgHTMLAttributes&lt;HTMLImageElement&gt; {}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ({ ...props }: ImageProps) =&gt; {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> {<span class="hljs-attr">...props</span>} /&gt;</span></span>;
};
</code></pre>
<p><strong>Note:</strong> I am using typescript to build this component. You can just remove typing if your project does not support typescript.</p>
<h4 id="2-how-to-use-image-in-app-page">2. How to use Image in App Page</h4>
<p>You can consume the Image component just like <code>img</code> HTML element. Since this image component extends <code>HTMLImageElement</code>. It supports all the Image properties.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// App.tsx</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/Image"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"section"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"title"</span>&gt;</span>React Components Demo<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"subtitle"</span>&gt;</span>Lazy Image<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
            <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">width:</span> <span class="hljs-attr">400</span>, <span class="hljs-attr">height:</span> <span class="hljs-attr">300</span> }}
            <span class="hljs-attr">src</span>=<span class="hljs-string">"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://doesnot.exits.com/image.png"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Try to reload the page, you will notice the image load very slowly. This is because the image is <code>10mb</code> large. Same time the other image will be broken.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602694964726/qv04HSX2y.png" alt="lazy_load_image1.png" /></p>
<h3 id="3-add-a-default-image-propplaceholder">3. Add a default image prop(placeholder)</h3>
<p>Let's add a default image prop, modify the interface.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// components/Image/index.tsx</span>

<span class="hljs-keyword">interface</span> ImageProps <span class="hljs-keyword">extends</span> React.ImgHTMLAttributes&lt;HTMLImageElement&gt; {
  placeholderImg?: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>Take <code>placeholderImg</code> image and show this to the user before the actual image loaded.</p>
<pre><code class="lang-js"><span class="hljs-comment">// components/Image/index.tsx</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ({ placeholderImg, src, ...props }: ImageProps) =&gt; {
  <span class="hljs-keyword">const</span> [imgSrc, setSrc] = useState(placeholderImg || src);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> {<span class="hljs-attr">...props</span>} <span class="hljs-attr">src</span>=<span class="hljs-string">{imgSrc}</span> /&gt;</span></span>;
};
</code></pre>
<p>No question will arise if we are showing a placeholder image, the how we will load the actual image. </p>
<p><img src="https://image.freepik.com/free-vector/flat-thinking-concept_23-2148163823.jpg" alt="thinking" /></p>
<h3 id="4-load-image-dynamically">4. Load Image Dynamically</h3>
<p>For that, we will use the <code>Image class</code> from JavaScript. We will create an image dynamically and add an event listener to it.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// components/Image/index.tsx</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ({ src, placeholderImg, ...props }: ImageProps) =&gt; {
  <span class="hljs-keyword">const</span> [imgSrc, setSrc] = useState(placeholderImg || src);

<span class="hljs-keyword">const</span> onLoad = useCallback(<span class="hljs-function">() =&gt;</span> {
    setSrc(src);
  }, [src]);

  useEffect(<span class="hljs-function">() =&gt;</span> {

    <span class="hljs-keyword">const</span> img = <span class="hljs-keyword">new</span> Image();
    img.src = src <span class="hljs-keyword">as</span> string;
    img.addEventListener(<span class="hljs-string">"load"</span>, onLoad);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      img.removeEventListener(<span class="hljs-string">"load"</span>, onLoad);
    };
  }, [src, onLoad]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> {<span class="hljs-attr">...props</span>} <span class="hljs-attr">alt</span>=<span class="hljs-string">{imgSrc}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{imgSrc}</span> /&gt;</span></span>;
};
</code></pre>
<p>Here we are using <code>useEffect</code> to create the image and load it in the background. We can listen to the load event using <code>addEventListener</code>. Once the image is loaded we can replace src with the actual src URL. Since the image has already loaded and cached to the browser. The next loading will be in no time.</p>
<p><strong>Since we are adding event listeners to the image on load and error on <strong>mount</strong> of the component. We should <strong>remove</strong> on unmount of the component.</strong></p>
<p>Let’s modify the App code.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// App.tsx</span>

&lt;Image
  style={{<span class="hljs-attr">width</span>: <span class="hljs-number">400</span>, <span class="hljs-attr">height</span>: <span class="hljs-number">300</span> }} 
  placeholderImg=<span class="hljs-string">"https://via.placeholder.com/400x200.png?text=This+Will+Be+Shown+Before+Load"</span>
  src=<span class="hljs-string">"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg"</span>
/&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
  <span class="hljs-attr">placeholderImg</span>=<span class="hljs-string">"https://via.placeholder.com/400x200.png?text=This+Will+Be+Shown+Before+Load"</span>
  <span class="hljs-attr">src</span>=<span class="hljs-string">"https://doesnot.exits.com/image.png"</span>
/&gt;</span></span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602695866539/O_Ay8fB_N.png" alt="lazy_load_image2.png" /></p>
<p>If you notice, the second image is still showing the placeholder image. Since the image never loaded successfully so <code>setSrc</code> never been called.</p>
<h3 id="5-handle-error-state">5. Handle Error State</h3>
<p>Let’s handle the image loading error. For that let’s add another prop <strong>errorImg</strong> and listen on <strong>error status</strong>.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// components/Image/index.tsx</span>

<span class="hljs-keyword">import</span> React, { useCallback, useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

interface ImageProps <span class="hljs-keyword">extends</span> React.ImgHTMLAttributes&lt;HTMLImageElement&gt; {
  placeholderImg?: string;
  errorImg?: string;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ({ src, placeholderImg, errorImg, ...props }: ImageProps) =&gt; {
  <span class="hljs-keyword">const</span> [imgSrc, setSrc] = useState(placeholderImg || src);

  <span class="hljs-keyword">const</span> onLoad = useCallback(<span class="hljs-function">() =&gt;</span> {
    setSrc(src);
  }, [src]);

  <span class="hljs-keyword">const</span> onError = useCallback(<span class="hljs-function">() =&gt;</span> {
    setSrc(errorImg || placeholderImg);
  }, [errorImg, placeholderImg]);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> img = <span class="hljs-keyword">new</span> Image();
    img.src = src <span class="hljs-keyword">as</span> string;
    img.addEventListener(<span class="hljs-string">"load"</span>, onLoad);
    img.addEventListener(<span class="hljs-string">"error"</span>, onError);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      img.removeEventListener(<span class="hljs-string">"load"</span>, onLoad);
      img.removeEventListener(<span class="hljs-string">"error"</span>, onError);
    };
  }, [src, onLoad, onError]);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> {<span class="hljs-attr">...props</span>} <span class="hljs-attr">alt</span>=<span class="hljs-string">{imgSrc}</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{imgSrc}</span> /&gt;</span></span>;
};
</code></pre>
<p>Let’s modify the App code.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// App.tsx</span>

<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/Image"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"section"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"title"</span>&gt;</span>React Components Demo<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"subtitle"</span>&gt;</span>Lazy Image<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
            <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">width:</span> <span class="hljs-attr">400</span>, <span class="hljs-attr">height:</span> <span class="hljs-attr">300</span> }}
            <span class="hljs-attr">placeholderImg</span>=<span class="hljs-string">"https://via.placeholder.com/400x200.png?text=This+Will+Be+Shown+Before+Load"</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg"</span>
          /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Image</span>
            <span class="hljs-attr">errorImg</span>=<span class="hljs-string">"https://image.shutterstock.com/image-vector/no-image-available-vector-illustration-260nw-744886198.jpg"</span>
            <span class="hljs-attr">placeholderImg</span>=<span class="hljs-string">"https://via.placeholder.com/400x200.png?text=This+Will+Be+Shown+Before+Load"</span>
            <span class="hljs-attr">src</span>=<span class="hljs-string">"https://doesnot.exits.com/image.png"</span>
          /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p><strong>Conclusion:</strong> Now we have achieved broken image and lazy loading image both with the same component.</p>
<p><strong>Note:</strong> You can use the placeholder image as a loader and show the loading image before loading the actual image. For that, you can use transition animation or Gif.</p>
<h4 id="codesandbox-domo">CodeSandbox Domo:</h4>
<iframe src="https://codesandbox.io/embed/react-lazy-load-image-yzwn6?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe>

<p>Thanks for your support. You can find all code in GitHub Repo: <a target="_blank" href="https://github.com/deepakshrma/react-components">deepakshrma/react-components</a> </p>
]]></content:encoded></item><item><title><![CDATA[Build a CLI Application | Deno By Example]]></title><description><![CDATA[If you have work for big organization, You must have built reusable and robust tool. That includes web, mobile and CLI Applications. A CLI will not only reduce the effort. It is also improve your CI/CD. Good CI/CD practice helps developer to achieve ...]]></description><link>https://blog.decipher.dev/build-a-cli-application-using-deno</link><guid isPermaLink="true">https://blog.decipher.dev/build-a-cli-application-using-deno</guid><category><![CDATA[Applications]]></category><category><![CDATA[command line]]></category><category><![CDATA[Deno]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Thu, 15 Oct 2020 06:09:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602743414499/yWI5UTMeQ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have work for big organization, You must have built reusable and robust tool. That includes web, mobile and CLI Applications. A CLI will not only reduce the effort. It is also improve your CI/CD. Good CI/CD practice helps developer to achieve their goal in simple and convenient way</p>
<p>We have seen how to create a basic <a target="_blank" href="https://decipher.dev/deno-by-example/02-greet-from-cli/">Greeting CLI</a> in another tutorial. Now we will extend our knowledge and create a <code>full-fledged</code> CLI which will be partially clone of Mac/Unix <code>find</code>.</p>
<img alt="Image for post" src="https://miro.medium.com/max/9792/1*6IOv24zYgd_Zt5iqYGridg.jpeg" />

<p>Photo by <a target="_blank" href="https://unsplash.com/@agkdesign?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alex Knight</a></p>
<p>Creating CLI required below mentioned features:</p>
<ol>
<li>Input command arguments parser</li>
<li>Traverse files and directory trees</li>
<li>Filter files/directory based on the arguments</li>
<li>Logger, better logging information</li>
</ol>
<h2 id="1-input-command-arguments-parser">1. Input command arguments parser</h2>
<pre><code class="lang-ts"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-built_in">console</span>.log(args);
}
main(Deno.args);
</code></pre>
<p>Taking arguments in <code>Deno</code>, It is very easy. Every process has <code>Deno.args</code>, which returns arguments passed to the program.</p>
<p><em>Run:</em></p>
<p><code>deno run examples/minifind.ts param1 param2</code></p>
<p><em>Output:</em></p>
<p><code>[ “param1”, “param2” ]</code></p>
<p><code>Deno.args</code> returns array of the string passed to the program(examples/minifind.ts).</p>
<p>Our CLI expects params like <code>type</code>, <code>name</code>, and <code>help</code>. To get the value of these parameters. We need to parse arguments. Deno has <code>flags</code> <a target="_blank" href="https://deno.land/std/flags/mod.ts">module</a> which helps to parse and collect parameters. Let's add <code>parser</code>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-keyword">const</span> {
    <span class="hljs-keyword">type</span>,
    name,
    not,
    help,
    _: [dir = <span class="hljs-string">"."</span>]
  } = parse(args);
  <span class="hljs-built_in">console</span>.log({
    <span class="hljs-keyword">type</span>,
    name,
    not,
    help,
    dir
  });
}
main(Deno.args);
</code></pre>
<p><em>Run:</em></p>
<pre><code class="lang-ts">deno run examples/minifind.ts --help --<span class="hljs-keyword">type</span>=f --<span class="hljs-keyword">type</span>=d --name=<span class="hljs-string">".*\.ts"</span> examples
</code></pre>
<p><em>Output:</em></p>
<pre><code class="lang-ts">{ <span class="hljs-keyword">type</span>: [ <span class="hljs-string">"f"</span>, <span class="hljs-string">"d"</span> ], name: <span class="hljs-string">".*\.ts"</span>, not: <span class="hljs-literal">undefined</span>, help: <span class="hljs-literal">true</span>, dir: <span class="hljs-string">"examples"</span> }
</code></pre>
<p>When you run the program with a given example, You will see the output as above. Deno parse helps you to collect all the arguments.</p>
<p>I have used the ES6 de-structuring feature to assign default values.</p>
<p>Deno parse automatically tries to collect and combine params based on patterns. Any argument passed as prefixing ( — ), considered as arguments with value. If you don't pass value next to it. It will become boolean.</p>
<p><em>Example 1:</em></p>
<pre><code class="lang-ts"><span class="hljs-built_in">console</span>.log(parse([<span class="hljs-string">"--test"</span>, <span class="hljs-string">"t"</span>])); <span class="hljs-comment">// { _: [], test: "t" }</span>
<span class="hljs-built_in">console</span>.log(parse([<span class="hljs-string">"--test"</span>])); <span class="hljs-comment">// { _: [], test: true }</span>
</code></pre>
<p>Things to be noted: If you pass an argument with the same param more than once. <code>parse</code> combine them in <code>array</code>. In the above example type is passed twice. That is why <code>type</code> has value <code>[ "f", "d" ]</code>.</p>
<p><em>Example 2:</em></p>
<pre><code class="lang-ts"><span class="hljs-built_in">console</span>.log(parse([<span class="hljs-string">"--test"</span>, <span class="hljs-string">"t"</span>, <span class="hljs-string">"--test"</span>, <span class="hljs-string">"t2"</span>]));

<span class="hljs-comment">// { _: [], test: [ "t", "t2" ] }</span>
</code></pre>
<p>underscore(<code>_</code>) here is like a collection of rest params. If arguments do not follow the standard <code>--</code> or <code>-</code> prefix. All arguments collected in <code>_</code> as an array of data. We are extracting <code>dir</code> as the directory name from rest <code>_</code>.</p>
<p><em>Example 3:</em></p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> { _ } = parse([<span class="hljs-string">"--test"</span>, <span class="hljs-string">"t"</span>, <span class="hljs-string">"examples"</span>]);
<span class="hljs-built_in">console</span>.log(_); <span class="hljs-comment">// _ == [ "examples" ]</span>
<span class="hljs-keyword">const</span> [dir = <span class="hljs-string">"."</span>] = _;
<span class="hljs-built_in">console</span>.log(dir);

<span class="hljs-comment">// examples</span>
</code></pre>
<p><strong>For more info read:</strong> <a target="_blank" href="https://deno.land/std/flags">https://deno.land/std/flags</a></p>
<h2 id="2-traverse-files-and-directory-trees">2. Traverse files and directory trees</h2>
<p>Since now we have arguments parsed, let’s add some logic to read the directory.</p>
<p>The first thing we can do, We can resolve the <code>path</code> or <code>directory</code> where files need to be searched. We can use the resolve method from the <a target="_blank" href="https://deno.land/std/path">path module</a>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { parse } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std/flags/mod.ts"</span>;
<span class="hljs-keyword">import</span> { resolve } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std/path/mod.ts"</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-keyword">const</span> {
    <span class="hljs-keyword">type</span>,
    name,
    not,
    help,
    _: [dir = <span class="hljs-string">"."</span>]
  } = parse(args);
  <span class="hljs-keyword">const</span> dirFullPath = resolve(Deno.cwd(), <span class="hljs-built_in">String</span>(dir));
  <span class="hljs-built_in">console</span>.log(dirFullPath);
}
main(Deno.args);
</code></pre>
<p><em>Run:</em></p>
<p><code>deno run -A examples/minifind.ts examples</code></p>
<p><em>Output:</em></p>
<p><code>_/Users/xdeepakv/github/deno-by-example/examples_</code></p>
<p><code>resolve</code> require <code>--allow-read</code> permission. For the time being, I have given all permission passing flag <code>-A</code>. you can read more about <a target="_blank" href="https://deno.land/manual/getting_started/permissions">permissions</a></p>
<p><code>Deno.cwd()</code> is used to get current running path. We had to convert <code>dir</code> as a string. Since <code>parse</code> can convert it to <code>string | number</code> based on the input type.</p>
<p>Reading a directory can be done using <code>Deno.readDir</code>. But we are traversing the entire tree of directories and files. Writing the traverse method can be tricky. You can try by yourself.</p>
<p>Here, I will take the help of <code>walk</code> function from <a target="_blank" href="https://deno.land/std/fs/mod.ts">https://deno.land/std/fs/mod.ts</a>.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { parse } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std/flags/mod.ts"</span>;
<span class="hljs-keyword">import</span> { resolve } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std/path/mod.ts"</span>;
<span class="hljs-keyword">import</span> { walk } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std/fs/mod.ts"</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-keyword">const</span> {
    <span class="hljs-keyword">type</span>,
    name,
    not,
    help,
    _: [dir = <span class="hljs-string">"."</span>]
  } = parse(args);
  <span class="hljs-keyword">const</span> dirFullPath = resolve(Deno.cwd(), <span class="hljs-built_in">String</span>(dir));
  <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">let</span> entry <span class="hljs-keyword">of</span> walk(dirFullPath)) {
    <span class="hljs-built_in">console</span>.log(entry);
  }
}
main(Deno.args);
</code></pre>
<p><em>Run:</em></p>
<p><code>deno run -A --unstable examples/minifind.ts examples</code></p>
<p><em>Output</em><strong><em>:</em></strong></p>
<pre><code class="lang-ts">{
 path: <span class="hljs-string">"/Users/xdeepakv/github/deno-by-example/examples/sample_employee.csv"</span>,
 name: <span class="hljs-string">"sample_employee.csv"</span>,
 isFile: <span class="hljs-literal">true</span>,
 isDirectory: <span class="hljs-literal">false</span>,
 isSymlink: <span class="hljs-literal">false</span>
}
{
 path: <span class="hljs-string">"/Users/xdeepakv/github/deno-by-example/examples/06_readfile_chunk.ts"</span>,
 name: <span class="hljs-string">"06_readfile_chunk.ts"</span>,
 isFile: <span class="hljs-literal">true</span>,
 isDirectory: <span class="hljs-literal">false</span>,
 isSymlink: <span class="hljs-literal">false</span>
}
</code></pre>
<p>Since <code>walk</code> function is not a stable function. We have to use <code>--unstable</code> flag while running the example.</p>
<p>Walk function returns an async generator of <code>entries</code>. Each entries have <code>name</code> and <code>path</code> along with other flags like <code>isDirectory</code> and <code>isFile</code>.</p>
<p><strong>Nice:</strong> The toughest part has been done. Now we can read entire directories along with files in it.</p>
<h2 id="3-filter-filesdirectory-based-on-the-arguments">3. Filter files/directory based on the arguments</h2>
<p>Walk function accepts <code>WalkOptions</code> as the second argument. We can use this option to add our logic.</p>
<p><em>Interface:</em></p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> WalkOptions {
  maxDepth?: <span class="hljs-built_in">number</span>;
  includeFiles?: <span class="hljs-built_in">boolean</span>;
  includeDirs?: <span class="hljs-built_in">boolean</span>;
  followSymlinks?: <span class="hljs-built_in">boolean</span>;
  exts?: <span class="hljs-built_in">string</span>[];
  match?: <span class="hljs-built_in">RegExp</span>[];
}
</code></pre>
<p><em>Code:</em></p>
<pre><code class="lang-ts"><span class="hljs-comment">// rest of the code</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-comment">// rest of the code</span>
  <span class="hljs-keyword">const</span> dirFullPath = resolve(Deno.cwd(), <span class="hljs-built_in">String</span>(dir));
  <span class="hljs-keyword">let</span> includeFiles = <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">let</span> includeDirs = <span class="hljs-literal">true</span>;
  <span class="hljs-keyword">let</span> types = <span class="hljs-keyword">type</span> ? (<span class="hljs-built_in">Array</span>.isArray(<span class="hljs-keyword">type</span>) ? <span class="hljs-keyword">type</span> : [<span class="hljs-keyword">type</span>]) : [<span class="hljs-string">"f"</span>, <span class="hljs-string">"d"</span>];
  <span class="hljs-keyword">if</span> (!types.includes(<span class="hljs-string">"f"</span>)) {
    includeFiles = <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">if</span> (!types.includes(<span class="hljs-string">"d"</span>)) {
    includeDirs = <span class="hljs-literal">false</span>;
  }
  <span class="hljs-keyword">const</span> options = {
    maxDepth: <span class="hljs-number">2</span>,
    includeFiles,
    includeDirs,
    followSymlinks: <span class="hljs-literal">false</span>,
    skip: [<span class="hljs-regexp">/node_modules/g</span>]
  };
  <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> entry <span class="hljs-keyword">of</span> walk(dirFullPath, options)) {
    <span class="hljs-built_in">console</span>.log(entry.path);
  }
}
main(Deno.args);
</code></pre>
<p><em>Run:</em></p>
<p><code>deno run -A --unstable examples/minifind.ts examples</code></p>
<p><em>Output:</em></p>
<pre><code class="lang-bash">/Users/xdeepakv/github/deno-by-example/examples
/Users/xdeepakv/github/deno-by-example/examples/subfolder
/Users/xdeepakv/github/deno-by-example/examples/subfolder/dummy.ts
</code></pre>
<p>The default type would include both <code>file</code> and <code>dir</code> ["f","d"] . Users can pass the flag <code>--type=f</code> and <code>--type=d</code> to override behavior.</p>
<p><strong><em>Run- Dirs only:</em></strong></p>
<p><code>deno run -A --unstable examples/minifind.ts --type=d examples</code></p>
<p><strong><em>Run- Files only:</em></strong></p>
<p><code>deno run -A --unstable examples/minifind.ts --type=f examples</code></p>
<p><code>WalkOptions</code> supports regexp to include and exclude patterns. We can use this to filter entries by name.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-comment">/// rest of the code</span>
  <span class="hljs-keyword">let</span> matchRegexps: <span class="hljs-built_in">RegExp</span>[] | <span class="hljs-literal">undefined</span> = name
    ? (<span class="hljs-built_in">Array</span>.isArray(name) ? name : [name]).map(
        <span class="hljs-function">(<span class="hljs-params">reg: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(reg)
      )
    : <span class="hljs-literal">undefined</span>;
  <span class="hljs-keyword">const</span> options = {
    maxDepth: <span class="hljs-number">2</span>,
    includeFiles,
    includeDirs,
    followSymlinks: <span class="hljs-literal">false</span>,
    match: matchRegexps,
    skip: [<span class="hljs-regexp">/node_modules/g</span>]
  };
  <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> entry <span class="hljs-keyword">of</span> walk(dirFullPath, options)) {
    <span class="hljs-built_in">console</span>.log(entry.path);
  }
}
main(Deno.args);
</code></pre>
<p><strong>Run- Get all file name have logger in it:</strong></p>
<p><code>deno run -A --unstable examples/minifind.ts --type=f --name=”.*logger.*” examples</code></p>
<p>Now we have working <code>minifind</code>. <strong>Noice</strong>!</p>
<h2 id="4-logger-better-logging-information">4. Logger, better logging information</h2>
<pre><code class="lang-ts"><span class="hljs-comment">/// rest of the code</span>
<span class="hljs-keyword">import</span> { Logger } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/deno_util/logger.ts"</span>;
<span class="hljs-keyword">const</span> usesFormat = <span class="hljs-string">`Uses:\n\n  minifind %s`</span>;
<span class="hljs-keyword">const</span> logger = <span class="hljs-keyword">new</span> Logger();
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printHelp</span>(<span class="hljs-params">command: <span class="hljs-built_in">string</span></span>) </span>{
  logger.info(<span class="hljs-string">`Welcome to minifind [v%s]`</span>, <span class="hljs-string">"1.0.0"</span>);
  logger.warn(usesFormat, command);
}
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params">args: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-comment">/// rest of the code</span>
  <span class="hljs-keyword">if</span> (help) {
    printHelp(<span class="hljs-string">`--type=f --name=".*logger.*" --help examples`</span>);
    Deno.exit(<span class="hljs-number">0</span>);
  }

  <span class="hljs-comment">/// rest of the code</span>
  <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> entry <span class="hljs-keyword">of</span> walk(dirFullPath, options)) {
    logger.inverse(entry.path);
  }
}
main(Deno.args);
</code></pre>
<p>The last missing piece is to tell your user about your CLI. For that, we have add helping messages for users. I am using <code>logger-util</code> created by me. You can read more here <a target="_blank" href="https://deno.land/x/deno_util">https://deno.land/x/deno_util</a>.</p>
<p><em>Run with help:</em></p>
<p><code>deno run -A --unstable examples/minifind.ts --help</code></p>
<p><em>Output:</em></p>
<p><img src="https://miro.medium.com/max/60/0*CbyaCwfMZQGLpBLN.png?q=20" alt="Image for post" /></p>
<img alt="Image for post" src="https://miro.medium.com/max/1600/0*CbyaCwfMZQGLpBLN.png" />

<p><em>Run with other options:</em></p>
<p><code>deno run -A --unstable examples/minifind.ts --help</code></p>
<p><em>Output:</em></p>
<p><img src="https://miro.medium.com/max/60/0*C0gh1DXteaV1fFU4.png?q=20" alt="Image for post" /></p>
<img alt="Image for post" src="https://miro.medium.com/max/1600/0*C0gh1DXteaV1fFU4.png" />

<p>TaDa! 👏👏 Now you know how to create a CLI.</p>
<h2 id="bonus">Bonus:</h2>
<p>Now we have working <code>minifind</code> CLI. However, we had to use <code>deno run</code> and <code>filename</code> to run the command, which is not <em>intended/feasible</em>. Deno provides <code>install</code> the command. Using that, We can convert any program to an <code>executable</code> tool.</p>
<p>Let’s convert our minifind to <code>executable</code>. It is very simple.</p>
<pre><code class="lang-bash">deno install -f --allow-read --unstable examples/minifind.ts
</code></pre>
<p>Once you run above command you will see output like:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Add /Users/xdeepakv/.deno/bin to PATH</span>

<span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"/Users/xdeepakv/.deno/bin:<span class="hljs-variable">$PATH</span>"</span>
</code></pre>
<p>If you see that, just add <code>export PATH="/Users/xdeepakv/.deno/bin:$PATH"</code> this line to your <code>.bashrc</code> or <code>.bash_profile</code>(Depending upon your OS type). Once you add <code>.deno/bin</code> in PATH. Open a new terminal and try below-mentioned command.</p>
<pre><code class="lang-bash">minifind --<span class="hljs-built_in">type</span>=f --name=<span class="hljs-string">".*logger.*"</span> examples
</code></pre>
<p>Now your <strong>minifind</strong> is ready to use for production(CLI). :-)</p>
<p><em>I hope you like this tutorial. Please have a look at some other tutorials on our website:</em> <a target="_blank" href="https://decipher.dev/deno-by-example/">https://decipher.dev/deno-by-example/</a></p>
<p>All working examples can be found in my Github: <a target="_blank" href="https://github.com/deepakshrma/deno-by-example/tree/master/examples">https://github.com/deepakshrma/deno-by-example/tree/master/examples</a></p>
]]></content:encoded></item><item><title><![CDATA[Build and Test A TypeScript library | Deno]]></title><description><![CDATA[Building and Testing A TypeScript/NodeJS library without WebPack, Jest or Rollup
No doubt Typescript is one of the best programming language/frameworks came in recent years. TypeScript helps you with the typings to write clean and modular JavaScript....]]></description><link>https://blog.decipher.dev/build-and-test-a-typescript-library-or-deno</link><guid isPermaLink="true">https://blog.decipher.dev/build-and-test-a-typescript-library-or-deno</guid><category><![CDATA[Testing]]></category><category><![CDATA[library]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Deno]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 13 Oct 2020 14:40:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602599645301/Bq6jKcF-_.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="building-and-testing-a-typescriptnodejs-library-without-webpack-jest-or-rollup">Building and Testing A TypeScript/NodeJS library without WebPack, Jest or Rollup</h2>
<p>No doubt Typescript is one of the best programming language/frameworks came in recent years. TypeScript helps you with the typings to write clean and modular JavaScript. However, Writing and setting up the library is a very tedious task. You can use TypeScript CLI to build a library, Still testing is a pain. In this tutorial, I will explain how you can ditch WebPack, Jest, or Rollup and write a beautiful library just using tools provided by <a target="_blank" href="https://deno.land/">Awesome Deno</a>.</p>
<p>Deno is around town for a while. Since the beginning, it getting the attention of the developers. It has runtime for JavaScript and TypeScript that uses V8 and is built-in Rust. Rust means, it is fast and secure at the same time.</p>
<p><img src="https://miro.medium.com/max/1400/1*7Ws9_cH2N2ZxvheAIn9f6A@2x.png" alt="Bundle Image" /></p>
<p>So how Deno will help you to ditch the things mentioned above. Let’s understand Deno a little bit. We will build a small nodejs/npm library using Deno just Deno.</p>
<h2 id="overview-of-library">Overview of library</h2>
<p>The library we are going to build will be lodash, Our own lodash. It will have some util methods like find unique, get values by props.</p>
<h2 id="initial-setup-for-library">Initial setup for library</h2>
<ol>
<li>Create folders and Initialize npm and git</li>
<li>Add basic test case and Implement the method <code>unique</code></li>
<li>Run and test it working</li>
</ol>
<h3 id="1-create-a-folders-and-initilize-npm-and-git">1. Create a folders and Initilize npm and git</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a folder</span>
md dash-lodash
md lib <span class="hljs-built_in">test</span>

<span class="hljs-comment">## Create files</span>
touch <span class="hljs-built_in">test</span>/index.js
touch lib/index.js

<span class="hljs-comment"># Git init</span>
git init
<span class="hljs-built_in">echo</span> <span class="hljs-string">".vscode\nnode_modules\nlib"</span> &gt; .gitignore

<span class="hljs-comment"># npm init</span>
npm init --y
</code></pre>
<p>If all good, You will see structure as below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602599762629/qPzFh1cyw.png" alt="deno_loadash_1.png" /></p>
<p><strong>Note:</strong>
If you noticed, I have added lib in <code>.gitignore</code>. Since we are building the TypeScript library. We will not need a <code>compiled</code> version of it.</p>
<h3 id="2-add-basic-test-case-and-implement-method-unique">2. Add basic test case and Implement method <code>unique</code></h3>
<p>Open file <code>test/index.js</code> and add below lines.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { unique } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../lib"</span>);

<span class="hljs-keyword">const</span> uniqueValues = unique([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>]);

<span class="hljs-keyword">if</span> (uniqueValues.length === <span class="hljs-number">4</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unique is not working"</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"✅ All looks good"</span>);
</code></pre>
<p>Open file <code>lib/index.js</code> and add below lines.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> unique = <span class="hljs-function">(<span class="hljs-params">arr</span>) =&gt;</span> arr;

<span class="hljs-built_in">module</span>.exports = { unique };
</code></pre>
<p>Open<code>package.json</code> add below lines</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"dash-lodash"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"lib/index.js"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"node test"</span>
  },
  <span class="hljs-attr">"keywords"</span>: [],
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>
}
</code></pre>
<h3 id="3-run-and-test-it-working">3. Run and test it working</h3>
<p>Since our npm is set now, You can run and test using <code>npm test</code> command. Once you run <code>npm test</code>, You will see error message like. <code>Error: Unique is not working</code></p>
<p>Add below code in <code>lib/index.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> unique = <span class="hljs-function">(<span class="hljs-params">arr</span>) =&gt;</span> [...new <span class="hljs-built_in">Set</span>(arr)];
<span class="hljs-built_in">module</span>.exports = { unique };
</code></pre>
<p>Run the test again, If you see the message <code>✅ All looks good</code> meaning all good to go. Your library is working.</p>
<h2 id="deno-as-typescript-runtime">Deno as TypeScript Runtime</h2>
<p>Our code is already running and tested. This is good to publish in npm. However, We want to use TypeScript as a source code. Good thing, The biggest selling point for Deno is TypeScript runtime. Saying that means you can run TypeScript without any external <code>trans-compiler</code>. Even you don't need <a target="_blank" href="https://www.typescriptlang.org/index.html#download-links">typescript cli</a>. Using Deno we can run typescript and same time Deno provides tools like a bundle. We can compile typescript and convert it to JavaScript.</p>
<p><strong>Prerequisite:</strong>
<em>Deno 1.1.0 and above</em></p>
<p>You can install Deno from here. <a target="_blank" href="https://Deno.land/#installation">installation</a></p>
<p>Let's move to TypeScript.</p>
<ol>
<li>Create a TypeScript lodash library</li>
<li>Update <code>npm scripts</code>, add Deno test task</li>
</ol>
<h3 id="1-create-a-typescript-lodash-library">1. Create a TypeScript lodash library</h3>
<pre><code class="lang-bash">md src
touch src/lodash.ts
</code></pre>
<p>Add below lines in file <code>src/lodash.ts</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> unique = <span class="hljs-function">(<span class="hljs-params">arr: any[]</span>) =&gt;</span> [...new <span class="hljs-built_in">Set</span>(arr)];
</code></pre>
<h3 id="2-update-npm-scripts-add-deno-test-task">2. Update <code>npm scripts</code>, add Deno test task</h3>
<p>Let's add a few test cases.</p>
<p>Since we are moving to Deno. We have to convert test cases to the <code>TypeScript</code> file.</p>
<pre><code class="lang-bash">touch <span class="hljs-built_in">test</span>/lodash.test.ts
</code></pre>
<p>Replace content of file with below given lines.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { assertEquals } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://Deno.land/std/testing/asserts.ts"</span>;
<span class="hljs-keyword">import</span> { unique } <span class="hljs-keyword">from</span> <span class="hljs-string">"../src/lodash.ts"</span>;

Deno.test(<span class="hljs-string">"unique #1"</span>, <span class="hljs-function">() =&gt;</span> {
  assertEquals(<span class="hljs-keyword">typeof</span> unique, <span class="hljs-string">"function"</span>, <span class="hljs-string">"Unique is not defined!"</span>);
});

Deno.test(<span class="hljs-string">"unique #2"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> uniqueValues = unique([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>]);
  assertEquals(uniqueValues.length, <span class="hljs-number">3</span>, <span class="hljs-string">"Unique is not working"</span>);
  assertEquals(uniqueValues, [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"✅ All looks good"</span>);
});
</code></pre>
<p>Update test command in <code>package.json</code></p>
<pre><code class="lang-json">{
  <span class="hljs-comment">// rest</span>
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"Deno test"</span>
  }
}
</code></pre>
<p>Run the test again. <code>npm test</code>. You will see a message like <code>test result: ok. 2 passed;</code></p>
<p>Now we have successfully moved our source code to typescript. However, If notice we cant directly consume our <code>src/lodash.ts</code> in nodejs. Our <code>dash-lodash</code> still pointing to <code>lib/index.js</code>. to consume this in nodejs. We need to convert typescript to JavaScript to consume in nodejs without webpack[bundler].</p>
<p>To convert <code>TypeScript</code> to <code>JavaScript</code>, we will use <a target="_blank" href="https://www.typescriptlang.org/index.html#download-links">typescript CLI</a> tool. To setup, bundler follow below given steps.</p>
<ol>
<li>Add typescript as dev dependencies</li>
<li>Add <code>tsconfig.json</code> file</li>
<li>Update <code>package.json</code></li>
</ol>
<p><strong>1. typescript as dev dependencies:</strong></p>
<p><code>npm i -D typescript</code></p>
<p><strong>2. Add <code>tsconfig.json</code> file:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"es6"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"CommonJS"</span>,
    <span class="hljs-attr">"declaration"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./lib"</span>,
    <span class="hljs-attr">"moduleResolution"</span>: <span class="hljs-string">"node"</span>
  },
  <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"src"</span>],
  <span class="hljs-attr">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>, <span class="hljs-string">"**/test/*"</span>]
}
</code></pre>
<p><strong>3. Update <code>package.json</code>:</strong></p>
<p>Add bundle command in <code>package.json</code></p>
<pre><code class="lang-json">{
  <span class="hljs-comment">// rest</span>
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"Deno test &amp;&amp; node test"</span>,
    <span class="hljs-attr">"bundle"</span>: <span class="hljs-string">"tsc"</span>
  }
}
</code></pre>
<p><strong>Run <code>bundle</code> command:</strong></p>
<p><code>npm run bundle</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1602599959381/JqLJgoKza.png" alt="deno_loadash_2.png" /></p>
<p><strong>Note:</strong>
We have to update, <code>test/index.js</code> import/require statement. Since <code>tsc</code> using <code>commonjs</code> as a module in <code>tsconfig.json</code>, All the files will be compiled and converted to the same name ie. <code>lib/lodash.js</code>.</p>
<p>After update, <code>test/index.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { unique } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../lib/lodash"</span>);

<span class="hljs-comment">// rest of the code</span>
</code></pre>
<p><strong>Try and run again test.</strong></p>
<blockquote>
<p><code>npm test</code> OR <code>node test</code></p>
</blockquote>
<p>Tada!! congrats you are all good to publish your nodejs-typescript module. To publish your module to npm you can follow <a target="_blank" href="https://zellwk.com/blog/publish-to-npm/">this</a> blog.</p>
<p><strong>Some final touch</strong>
TypeScript module need to define the type defination locaction. We can add meta data for that in <code>package.json</code></p>
<p>Add below lines in <code>package.json</code></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"dash-lodash"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"\"demo deno typescript, testing bundling\""</span>,
  <span class="hljs-attr">"types"</span>: <span class="hljs-string">"lib/lodash.d.ts"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"lib/lodash.js"</span>,
  <span class="hljs-attr">"files"</span>: [<span class="hljs-string">"lib/lodash.js"</span>]
  <span class="hljs-comment">//rest of the code</span>
}
</code></pre>
<p>Once you publish your module on npm. You can use your module as below.</p>
<p><strong>In NodeJS:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { unique } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"dash-lodash"</span>);

<span class="hljs-keyword">const</span> uniqueValues = unique([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>]);

<span class="hljs-keyword">if</span> (uniqueValues.length === <span class="hljs-number">4</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unique is not working"</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"✅ All looks good"</span>);
</code></pre>
<p><strong>In TypeScript:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { unique } <span class="hljs-keyword">from</span> <span class="hljs-string">"dash-lodash"</span>;

<span class="hljs-keyword">const</span> uniqueValues = unique([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">1</span>]);

<span class="hljs-keyword">if</span> (uniqueValues.length === <span class="hljs-number">4</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Unique is not working"</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"✅ All looks good"</span>);
</code></pre>
<p>For source code, You can refer to <a target="_blank" href="https://github.com/deepakshrma/dash-lodash-deno-typescript-sample">dash-lodash-deno-typescript-sample</a> repo.</p>
<p>Thanks. Keep Calm, Keep Coding.</p>
<div id="93e7bc2a_1599917840">
</div>]]></content:encoded></item><item><title><![CDATA[Error Handling | Simplified | Javascript]]></title><description><![CDATA[Javascript is a dynamic language. This makes Javascript a supercool language. However, Same time it is very hard to write secure code. One small mistake can lead to a bigger issue. Error handling plays a vital role to reduce the number of bugs. If yo...]]></description><link>https://blog.decipher.dev/error-handling-or-simplified-or-javascript</link><guid isPermaLink="true">https://blog.decipher.dev/error-handling-or-simplified-or-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[error handling]]></category><category><![CDATA[clean code]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 13 Oct 2020 14:31:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602599459394/kwoQdGycL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn-images-1.medium.com/max/1440/0*xe7Z_KiUCiwSNKDg" alt="img1" /></p>
<p>Javascript is a dynamic language. This makes Javascript a supercool language. However, Same time it is very hard to write secure code. One small mistake can lead to a bigger issue. Error handling plays a vital role to reduce the number of bugs. If you handle error elegant way, it will save a lot of time in the future. So the bigger question is how you should handle the error.</p>
<p>Let's take one example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();
app.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">_, res</span>) =&gt;</span> res.end(<span class="hljs-string">"OK"</span>));
app.listen(<span class="hljs-number">80</span>);
</code></pre>
<p>The above code is a sample code written in nodejs on an <a target="_blank" href="https://expressjs.com/">express</a> framework. This code trying to run a server at port 80. What if we know that port 80 is already taken by some other app and we try to run the above code. How do we know what will happen? Will it run or break with some error? This is very unclear while seeing this code. Even you want to handle an error, you may have to read the documentation. But don’t worry, just like any natural language. The programming language has some grammar. Even there is no standard specification in ECMA standard for Error handling. But the Javascript community follows certain coding guidelines.</p>
<h3 id="topics">Topics</h3>
<ol>
<li>Types of Errors</li>
<li>How To Handle Errors<ol>
<li>Synchronous<ol>
<li>try-catch</li>
</ol>
</li>
<li>Asynchronous<ol>
<li>callback-error-data</li>
<li>promise-then-catch</li>
<li>try-catch-await</li>
</ol>
</li>
</ol>
</li>
<li>Custom Error</li>
<li>Advanced Error Handling<ol>
<li>Error handle with Loop</li>
<li>Multiple errors in try-catch</li>
<li>Multiple errors in promise-then-catch</li>
</ol>
</li>
<li>Error Handling Coding Practices</li>
</ol>
<h2 id="types-of-errors">Types of Errors</h2>
<p>Since JavaScript has a different flavor of the compiler and most of the have written and maintained by a different organization. Except for <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a>, There is no very definite or consistent distribution among the type of error. Even the message varies compiler to compiler. However, You can find a list fo the errors<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">here</a>. Since Javascript is a dynamic language, most of the errors are runtime errors.</p>
<p><strong>Example:</strong></p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Number</span>(<span class="hljs-number">10</span>).toPrecision(<span class="hljs-number">200</span>));
</code></pre>
<p>If we run the above code, It will throw RangeError. <code>RangeError: toPrecision() argument must be between 1 and 100</code></p>
<h2 id="how-to-handle-error">How to handle Error</h2>
<p>Base on the nature of the API(method) call sync/async, Error can be handle differently.</p>
<h3 id="synchronous">Synchronous</h3>
<p><strong>try-catch:</strong> You can use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try-catch</a> block to handle Synchronous error.</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Number</span>(<span class="hljs-number">10</span>).toPrecision(<span class="hljs-number">200</span>));
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-comment">// RangeError: toPrecision() argument must be between 1 and 100</span>
  <span class="hljs-built_in">console</span>.log(error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">RangeError</span>); <span class="hljs-comment">// true</span>
}
</code></pre>
<p>If you don't want to catch the error and perform any operation. In the newer version of JavaScript compiler you can do so.</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Number</span>(<span class="hljs-number">10</span>).toPrecision(<span class="hljs-number">200</span>));
} <span class="hljs-keyword">catch</span> {}
</code></pre>
<p>If you want to perform some default operation on error, You can use finally block after the catch block.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> average;
<span class="hljs-keyword">try</span> {
  average = getAverage(); <span class="hljs-comment">// Sum function does not exits.</span>
} <span class="hljs-keyword">catch</span> {
} <span class="hljs-keyword">finally</span> {
  average = <span class="hljs-number">0</span>;
}
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Average is <span class="hljs-subst">${average}</span>`</span>);
<span class="hljs-comment">// Average is 0</span>
</code></pre>
<p>Finally block is mainly used to clean the resources like some <strong>open file</strong>, <strong>open</strong> <strong>connection</strong>.</p>
<p><img src="https://cdn-images-1.medium.com/max/1440/0*VB_fvm1LnN39nOcg" alt="img2" /></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@nordwood">NordWood Themes</a> on <a target="_blank" href="https://unsplash.com">Unsplash</a></p>
<p><strong>Asynchronous:</strong></p>
<p>An API is called asynchronous in nature when the outcome will come on some next event cycle of the EventLoop. Normally, All network call and IO operation are an async in nature. To get data from async call we either use callback or promise object.</p>
<p><strong>Error handle in async-callback API(callback-error-data):</strong> Core Browser base javascript has very limited async APIs. You can create an async function either using timer APIs like <strong>setTimeout</strong> and <strong>setInterval</strong> Or you can create an <strong>AJAX</strong> call using <strong>fetch</strong>. <strong>setTimeout</strong> and <strong>setInterval</strong> do not throw any such error that can be handle. And fetch is a promised based async call(We will learn later to handle promise-based error). However, nodejs has a lot of standards and third-party APIs which throws an error. Just like our first express.js example.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();
app.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">_, res</span>) =&gt;</span> res.end(<span class="hljs-string">"OK"</span>));

<span class="hljs-keyword">const</span> server = app.listen(<span class="hljs-number">80</span>);
server.on(<span class="hljs-string">"error"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleListen</span>(<span class="hljs-params">error</span>) </span>{
  <span class="hljs-built_in">console</span>.log(error);
});
</code></pre>
<p>Here in the above example, Express does not try to handle error for you. Instead, it returns the core <a target="_blank" href="https://nodejs.org/api/http.html#http_event_clienterror">server</a> instance of nodejs. You can catch error on the error handler callback function.</p>
<p>Nodejs follows certain rules. As a <a target="_blank" href="https://nodejs.org/api/errors.html">coding standards</a>, all the async APIs accept a callback. In the callback, the first argument will be an error generated by API and the second argument will be data on success. This standard has been followed by the overall community too.</p>
<pre><code class="lang-js">fs.readFile(<span class="hljs-string">"a file that does not exist"</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"There was an error reading the file!"</span>, err);
    <span class="hljs-keyword">return</span>;
  }
  <span class="hljs-comment">// Otherwise handle the data</span>
});
</code></pre>
<p><strong>Info:</strong>
You can not handle async callback error in <strong>try-catch</strong> block. However, there is an exception. A recent version of ECMA Script, using async-await now we can handle error in try-catch. We will learn that later.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This will not work</span>

<span class="hljs-keyword">try</span> {
  app.listen(<span class="hljs-number">80</span>);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-comment">// never called</span>
  <span class="hljs-built_in">console</span>.error(error);
}
</code></pre>
<p><strong>Error handle in promise-based API(try-catch-await):</strong> After ES5, Javascript introduce a new design pattern to handle callback for async API. That is a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promise design pattern</a>. This solves the previous issue of callback hell.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> promise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">response, reject</span>) =&gt;</span> {
  <span class="hljs-comment">// some async code here</span>
});

promise
  .then(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onSuccess</span>(<span class="hljs-params">data</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"SUCCESS"</span>);
  })
  .catch(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onError</span>(<span class="hljs-params">err</span>) </span>{
    <span class="hljs-built_in">console</span>.error(err);
  });
</code></pre>
<p>To get error form a promise object, you have to use the catch method and pass a callback function. To understand the <a target="_blank" href="https://www.tothenew.com/blog/angularjs-deferred-promises-basic-understanding/">promise/deferred</a> pattern, You can read my blog <a target="_blank" href="https://www.tothenew.com/blog/angularjs-deferred-promises-basic-understanding/">here</a>.</p>
<p>The promise is much cleaner than that callback. However, It is very hard to understand the flow in a big codebase. The recent version of ECMA Script has introduced <a target="_blank" href="https://javascript.info/async-await">async-await</a>. Using async-await we can write asynchronous code in a synchronous way.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">await</span> promise1;
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> promise2;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error); <span class="hljs-comment">// SOME ERROR</span>
  }
}
main();
</code></pre>
<p>Using <strong>try-catch-await</strong>, you can handle multiple errors in one block which was not possible/complicated in the <strong>promise-then-catch</strong> pattern.</p>
<p>Now we know how to handle the error. However, while writing code we don’t have to handle error only. We may want to create a custom error. This will help to write clean and maintainable code. It is good practice, you should create custom errors for business logics</p>
<p><img src="https://cdn-images-1.medium.com/max/1440/0*xETNVRQX05UU0UZM" alt="img3" /></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@isisfra">Isis França</a> on <a target="_blank" href="https://unsplash.com">Unsplash</a></p>
<h3 id="custom-error">Custom Error</h3>
<p>Creating a custom error is very simple. You can use any custom class and throw it as an error.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeNetworkError</span> </span>{
  <span class="hljs-keyword">constructor</span>(status) {
    <span class="hljs-built_in">this</span>.status = status;
  }
}
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> SomeNetworkError(<span class="hljs-number">4000</span>);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-built_in">console</span>.log(error <span class="hljs-keyword">instanceof</span> SomeNetworkError); <span class="hljs-comment">// true</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`SomeNetworkError Status: <span class="hljs-subst">${error.status}</span>`</span>); <span class="hljs-comment">// SomeNetworkError Status: 4000</span>
}
</code></pre>
<p>Above we have SomeNetworkError class and we use an instance of this class to throw an error. This is a valid code. However, as a coding practice, we should extend default(standard) error-classes. The base of all error-class is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Constructor">Error</a> and call with a super method with the message.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SomeNetworkError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Error</span> </span>{
  <span class="hljs-keyword">constructor</span>(message, status) {
    <span class="hljs-built_in">super</span>(message);
    <span class="hljs-built_in">this</span>.status = status;
  }
}
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> SomeNetworkError(<span class="hljs-string">"Network Error"</span>, <span class="hljs-number">4000</span>);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-built_in">console</span>.error(error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span>); <span class="hljs-comment">// true</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`&gt; <span class="hljs-subst">${error}</span>`</span>); <span class="hljs-comment">// &gt; Error: Network Error</span>
  <span class="hljs-built_in">console</span>.error(error); <span class="hljs-comment">// SomeNetworkError: Network Error</span>
  <span class="hljs-built_in">console</span>.error(error.stack); <span class="hljs-comment">// stacktrace here</span>
}
</code></pre>
<p>If you notice, extending the Error class and calling super automatically get .<strong>toString</strong> method of the SomeNetworkError class and print a nice message. Similarly, you can extend other standard Error class too.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ArithmeticRangeError</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RangeError</span> </span>{
  <span class="hljs-keyword">constructor</span>(message) {
    <span class="hljs-built_in">super</span>(message);
  }
}
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> zero = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">if</span> (zero === <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArithmeticRangeError(<span class="hljs-string">"zero cant be 0"</span>);
  }
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-built_in">console</span>.log(error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">RangeError</span>); <span class="hljs-comment">// true</span>
  <span class="hljs-built_in">console</span>.error(error.toString()); <span class="hljs-comment">// RangeError: zero cant be 0</span>
}
</code></pre>
<h3 id="advanced-error-handling">Advanced Error Handling</h3>
<p><strong>Error handle with Loop:</strong> Keep try-catch out of the loop, if you want to break loop on error. Else put try-catch inside a loop to continue</p>
<p><strong>Break on error:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>];
  numbers.forEach(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (num === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArithmeticRangeError(<span class="hljs-string">"zero cant be 0"</span>);
    }
    <span class="hljs-built_in">console</span>.log(num);
  });
} <span class="hljs-keyword">catch</span> (error) {}
</code></pre>
<p><strong>Continue on error or skip:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>];
numbers.forEach(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">if</span> (num === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArithmeticRangeError(<span class="hljs-string">"zero cant be 0"</span>);
    }
  } <span class="hljs-keyword">catch</span> (error) {}
  <span class="hljs-built_in">console</span>.log(num);
});
</code></pre>
<p><strong>Without try-catch, Logical handle:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// filter zero, no need handle zero</span>

<span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>].filter(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> num !== <span class="hljs-number">0</span>);
numbers.forEach(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(num);
});

<span class="hljs-comment">// Use some to break loop</span>

<span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>];

numbers.some(<span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> isZero = num === <span class="hljs-number">0</span>;
  <span class="hljs-keyword">if</span> (isZero) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  <span class="hljs-comment">// logic here</span>
  <span class="hljs-built_in">console</span>.log(num);
});
</code></pre>
<p>As you can see, based on your need you may not need to throw error always. You can handle it logically.</p>
<p><strong>Multiple errors in try-catch:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">let</span> name;
  <span class="hljs-comment">/// some operation</span>
  <span class="hljs-keyword">if</span> (name === <span class="hljs-string">""</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">RangeError</span>(<span class="hljs-string">"Cant be blank"</span>);
  <span class="hljs-keyword">if</span> (name.match(<span class="hljs-regexp">/\W/</span>)) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(<span class="hljs-string">"name cant be non alph-numric"</span>);
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Some other error"</span>);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">RangeError</span>) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"RangeError"</span>);
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">TypeError</span>) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"TypeError"</span>);
  <span class="hljs-keyword">else</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Other Error"</span>);
}
</code></pre>
<p><strong>Multiple errors in promise-then-catch:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
  <span class="hljs-keyword">let</span> name;
  <span class="hljs-comment">// some logic</span>
  resolve(name);
})
  .then(<span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (name === <span class="hljs-string">""</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">RangeError</span>(<span class="hljs-string">"Cant be blank"</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> name;
  })
  .then(<span class="hljs-function">(<span class="hljs-params">name</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (name.match(<span class="hljs-regexp">/\W/</span>)) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TypeError</span>(<span class="hljs-string">"name cant be non alph-numric"</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> name;
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">RangeError</span>) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"RangeError"</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">TypeError</span>) <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"TypeError"</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Other Error"</span>);
  });
</code></pre>
<h3 id="error-handling-coding-practices">Error Handling Coding Practices</h3>
<p>Above all code are very standard and simple use cases to handle the error. However, when you work on the project. The code maybe not this simple as it is given here. So we need to write some boilerplate codes. Below, I have listed some of the patterns that I follow in my projects.</p>
<ol>
<li>Create <strong>Enum</strong> Class or Error <strong>Constants</strong></li>
<li>Use <strong>localization</strong> from beginning</li>
<li>Common <strong>util module or file</strong> to handle logic and generate an error</li>
<li>Try to <strong>minimize</strong> try-catch uses, Instead write more unit test cases</li>
<li>Catch and Throw a <strong>custom error</strong> on API calls</li>
<li>Use <strong>typescript</strong> as much as possible</li>
<li>Minimize the use of magic number/string</li>
<li>Avoid higher level of <strong>nested object</strong></li>
<li>Avoid global <strong>object pollution</strong></li>
<li>Use <a target="_blank" href="https://reactjs.org/docs/error-boundaries.html"><strong>Error-Boundaries</strong></a> as much as possible(React)</li>
<li>Proper logging, use <strong>console.error</strong> for error logging.</li>
<li><strong>Log level</strong> to minimize log messages</li>
<li>Don’t print <strong>credential</strong> in logs</li>
<li>Use <strong>more visuals</strong> than console in the case of WebApps.</li>
</ol>
<div id="93e7bc2a_1599917840">
</div>]]></content:encoded></item><item><title><![CDATA[Security Vulnerability Solutions for Non-Tech People | In Simple Language]]></title><description><![CDATA[In the world of data, the Security of personal data is the biggest concern of anyone. Knowingly or unknowingly we share a lot of data to the company like Google and Facebook. In the old era, we have made walls/doors to protect our property from exter...]]></description><link>https://blog.decipher.dev/security-vulnerability-solutions-for-non-tech-people-or-in-simple-language</link><guid isPermaLink="true">https://blog.decipher.dev/security-vulnerability-solutions-for-non-tech-people-or-in-simple-language</guid><category><![CDATA[Security]]></category><category><![CDATA[networking]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[privacy]]></category><category><![CDATA[data]]></category><dc:creator><![CDATA[Deepak Vishwakarma]]></dc:creator><pubDate>Tue, 13 Oct 2020 14:24:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1602599154948/6vxDGv7CC.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of data, the Security of personal data is the biggest concern of anyone. Knowingly or unknowingly we share a lot of data to the company like Google and Facebook. In the old era, we have made walls/doors to protect our property from external threats. So now how far you will go to protect you and your beloved property.</p>
<pre><code class="lang-text">In this article, I will explain how you can protect your data using some basic tips. You don't have to be super technical to protect you.
</code></pre>
<p><img src="https://miro.medium.com/max/1400/0*8JJZtx7xkP-NL0ZE" alt="img 1" /></p>
<h2 id="overview">Overview</h2>
<p>To protect your assets, First, you have to understand what assets do you have with you. Data is everywhere. First thing you see, when you wake-up could be mobile and laptop, based on age. If you close to teen, most probably mobile and your messengers. As you terns on mobile, You start sharing data. You have like multiple messaging apps like Whatsapp/Facebook/WeChat.</p>
<h3 id="1-advertisementads-phishing">1. Advertisement(Ads) Phishing</h3>
<p>So question is, how much you should concern about your data? To understand that let’s understand the revenue model of Facebook, Google, and other tech giants.</p>
<p><img src="https://miro.medium.com/max/668/1*_H0IMcKs6bLYZEqeWTnkCA.jpeg" alt="f 1" />
<img src="https://miro.medium.com/max/668/1*-3k9OFN1yyljr_yWaIrQRA.jpeg" alt="f 1" />
<img src="https://miro.medium.com/max/668/1*NuvXpT2RZqxSgVGCmwcq1Q.jpeg" alt /></p>
<p>You can clearly guess, Your small data is the 98.5% revenue for Facebook. In last year, The yearly estimated revenue for Facebook was around <code>70 Billion</code> [source]. The total number of users on Facebook is around <code>2.6 billion</code> [source]. So you contribute, almost <code>~27$</code> to Facebook yearly. If you have 5 members at your home, So around <code>100$</code> just watching videos and memes on Facebook.</p>
<p>:::note Fact Check:
<strong>Out of 2.6 billion, 1.8 billion are real accounts. Rest are either fake or bots.</strong>
:::</p>
<p><img src="https://miro.medium.com/max/1400/1*niLh4nQqQYSj6TLebfsAnA.jpeg" alt="img 3" /></p>
<p>Other companies are not far away. A company like <a target="_blank" href="https://en.wikipedia.org/wiki/WeChat">WeChat</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/TikTok">TikTok</a> goes extra miles. You event track your key movements.</p>
<p><strong>Read More:</strong> <a target="_blank" href="https://www.businessofapps.com/data/tik-tok-statistics/">https://www.businessofapps.com/data/tik-tok-statistics/</a></p>
<p><img src="https://miro.medium.com/max/1400/1*zbQdWBSdO4rl55zwWHbIbg.jpeg" alt="img 4" /></p>
<h3 id="2-sharing-is-not-caring">2. Sharing is not caring</h3>
<p>This tag line does not work for the data. Personal information is the worst thing to share with someone else. The more you share information, The more you will become vulnerable.
<strong>Google</strong> is the biggest example of that. Whenever you search for something on Google. You actually let Google know, what may you can buy in the next few weeks. And Google starts sending you a <strong>Focused message</strong>, <strong>notification</strong> to remind you what you should buy. To understand this effect, You should watch the 2015 movie <a target="_blank" href="https://en.wikipedia.org/wiki/Focus_(2015_film">Focus</a>&gt;).</p>
<p>One day, I search for how to learn swimming. The next day, I see ADs of the Eyes protection glass Ads as a suggestion on multiple websites. The biggest among those, When I actually decided to buy the glasses and I visit <a target="_blank" href="https://en.wikipedia.org/wiki/Lazada_Group">Lazada</a>(one of the shopping app in Singapore). I saw same glasses in my recommended section. It was the <strong>WTF</strong> moment for me.</p>
<p>So definitely sharing is not caring.</p>
<p>To understand how prediction(Not Suggestion) algorithms work for Google. You can read <a target="_blank" href="https://www.blog.google/products/search/how-google-autocomplete-works-search/">https://www.blog.google/products/search/how-google-autocomplete-works-search/</a></p>
<p><img src="https://miro.medium.com/max/1400/0*XwaXMgaP-ZgUZl4Z" alt="img 5" /></p>
<h2 id="3-the-solution-is-the-problem">3. The solution is the problem</h2>
<p>Previously, The quote was <strong>“necessity is the mother of innovation”</strong>. That is changed not to <strong>“problem is the source of innovation”</strong>. Meaning, The new moto around the tech world is, Find a problem and solve it better than the others.</p>
<p><img src="https://miro.medium.com/max/1400/0*yzjZXQpd_VRKGDFf" alt="img 6" /></p>
<p>Let’s discuss a scenario. I have a small cotton business, I won't open my own store and sell product online. Ok. So I need to buy a <strong>domain</strong> and I need to <strong>create a website</strong> and <a target="_blank" href="https://cloud.google.com/solutions/web-hosting">host on platform</a>. You will say, The title was this article is for non-technical. But now i am getting too technical. But you have to understand this.</p>
<p><img src="https://miro.medium.com/max/668/1*NuvXpT2RZqxSgVGCmwcq1Q.jpeg" alt="img 7" />
<img src="https://miro.medium.com/max/668/1*IWcHuR30-sUl_RXl7hJkLw.jpeg" alt="img 8" />
<img src="https://miro.medium.com/max/668/1*-3k9OFN1yyljr_yWaIrQRA.jpeg" alt="img 8" /></p>
<p>No doubt, <strong>AWS(Amazon Web Service)</strong> is ahead in this field. However, does it worth investing money on something which is wearing more than me ??</p>
<p>Companies in banking sectors, Invest <strong>huge amounts</strong> of <strong>money</strong> to buy the products and use it in name of <strong>simplicity</strong>. But the question we should ask, Do we <strong>really needed</strong> it?</p>
<p>You can ask a question where is data(personal) here. The answer is, you are right there is no real data-data shared here. But you are given an idea of data to these companies so that they can find the solution to a problem which never exits or can be solved simply.</p>
<p>:::info
This is mostly applicable to big companies. And very much opinionating. :-D
:::</p>
<p><strong>Solution:</strong> So mota-moti(a Hindi word for roughly), We have a few problems to solve. So how??</p>
<blockquote>
<p>The answer is very simple. <code>Delete the App.</code></p>
</blockquote>
<p>I did so. Past few months, I am using my mobile without <strong>Facebook</strong>, <strong>Instagram</strong>, and <strong>Chrome</strong>. I never have to install <strong>TikTok</strong> for more than 10min. That also to watch, what are the feature provided by TikTok.</p>
<p><img src="https://miro.medium.com/max/1400/0*Oh8CtClmiPwSJgYI" alt="img 9" /></p>
<p><em>Deleting is not the proper solution. In this era of data, You don't want to be backward by not letting you learn something new. So what to do.</em></p>
<p><strong>Browser:</strong></p>
<pre><code class="lang-text">Recently, I found the Browser like Brave. The tagline for Brave is You deserve a better Internet. Yes, We do deserve. This browser is built on top Chromium which is the open-source version of the chrome. Meaning that it is the most closet thing you can get as an alternative to Chrome.

Brave, does not track your activity without your permission. You let the browser to track you, you get paid for your data. To understand more, Please just go to there landing page. https://brave.com/
</code></pre>
<p><strong>Search Engine:</strong></p>
<pre><code class="lang-text">Brave comes with multiple search engines, including Google and Duck Duck Go. I start using DuckDuckGo. The search result is not as good as Google(reason less data capture). But it has lots of good features like rating of the page. Every time you open a page you see rating of the page. A grade with green signal is a good sign for your data security.
</code></pre>
<p><img src="https://miro.medium.com/max/892/1*QT4K1AoI-qQ1Ab8y-qZedQ.png" alt="img 10" />
<img src="https://miro.medium.com/max/806/1*O8z_xTu1snVY5F1J0nHkWg.png" alt="img 10" /></p>
<p>You can go and check out https://duckduckgo.com/app</p>
<p><strong>Alternative to Apps:</strong></p>
<p>In the end, how we can use social sites without the apps. I know it is tough, I have deactivated few of my social networking account. But you don’t have to be hard on your self. Most of the app has a website for there products. If you are only visitor, not contributors. You can view all the posts from your friends on the browser and still connected with friends. Like I use Instagram, on my Brave browser. I know I can't upload pics here. But good for me till now.</p>
<p><code>text title="Quotes of the Day"
 "Change is painful but Change is good for you"</code></p>
<p><img src="https://miro.medium.com/max/1400/0*Pe7-Vi6-ecc86P8U" alt="img 11" /></p>
<div id="93e7bc2a_1599917840">
</div>]]></content:encoded></item></channel></rss>