<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Doaa Mahely</title>
    <description>The latest articles on DEV Community by Doaa Mahely (@dmahely).</description>
    <link>https://dev.to/dmahely</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F57124%2Fdf42dc54-3838-4e01-a5fb-e4e27f46e7f9.jpeg</url>
      <title>DEV Community: Doaa Mahely</title>
      <link>https://dev.to/dmahely</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmahely"/>
    <language>en</language>
    <item>
      <title>A day in the life, Ramadan edition</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Fri, 23 Apr 2021 15:21:09 +0000</pubDate>
      <link>https://dev.to/dmahely/a-day-in-the-life-ramadan-edition-10h</link>
      <guid>https://dev.to/dmahely/a-day-in-the-life-ramadan-edition-10h</guid>
      <description>&lt;p&gt;It's that time of year again, when billions of Muslims start fasting from dawn until dusk. Ramadan timings depend on the Islamic lunar calendar, which makes it shift around 10 or 11 days every year. So for the last decade, it always happened in the summer when it is very hot and humid where I live. Luckily, summer vacation meant that I didn't have to go to school or university while fasting. This year is my second year fasting while working full time, and I thought I'd share how it's going and the impact it has on me.&lt;/p&gt;

&lt;p&gt;Since I live in a majority Muslim country, work hours are reduced by law during Ramadan. The usual 9-hour work day in the private sector is reduced to 7 hours, minus the extra hour or half hour that was for your lunch break. At my current workplace, I was able to choose whether to work 9AM - 3PM or 10AM - 4PM. Being anything but a morning person, I opted to start the day at 10AM. Some companies take it even further and allow for more flexibility, only maintaining that employees work their hours whenever suits them.&lt;/p&gt;

&lt;p&gt;Many people report that they can focus better and reach a flow state easier while fasting. Unfortunately, that isn't the case for me! In the last few years, I realized a couple of things about my productivity: I'm pretty slow in the morning, and I get my first burst of energy in the afternoon. Then I &lt;em&gt;really&lt;/em&gt; get going and produce my best work late at night.&lt;/p&gt;

&lt;p&gt;Because of this, I try to do certain types of work during particular hours. For example, I don't like starting the day with meetings or talking to people. My favorite morning activity is debugging or conducting code reviews because I can just focus on one thing without having to think too much, and I don't have to do any synchronous communication. Then, in the afternoon, I usually get to follow ups and meetings and start coding.&lt;/p&gt;

&lt;p&gt;I'm an insomniac and no matter what, I always get a lot of energy close to 10PM. I used to pick up some work tasks at night if I felt I was behind or just didn't have anything better to do. However, since the pandemic started and working from home has been thrust upon us, I've been careful to separate my working hours from my non-working hours. &lt;/p&gt;

&lt;p&gt;Now, I wouldn't say I'm necessarily into music, but I only realized how hard it is for me to get into a flow without it last Ramadan. That's because I stop listening to music during the month out of discipline. I experimented with podcasts, audiobooks and those deep focus music videos on YouTubes with no luck. Then, I started playing TV shows and movies in the background just so I can have something to hear, and that helped me focus (and understand and catch up on a lot of pop culture!).&lt;/p&gt;

&lt;p&gt;Personally, Ramadan is the only month a year I can maintain a daily routine. That's because every day looks more or less the same: I wake up, work, eat, pray, read and unwind at the same time. Plus, my social calendar gets cleared up, as I don't schedule any appointments and cut back on gatherings and going out. So I grabbed the opportunity and started spending two hours a day on dedicated learning and working on side projects. It's been fun being consistently productive and I hope I'll be able to continue this trend till the end of the month.&lt;/p&gt;




&lt;p&gt;Thanks for reading 👋 Until next time.&lt;br&gt;
&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@rawanyasser"&gt;Rawan Yasser&lt;/a&gt; on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>All About Closures</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Tue, 06 Apr 2021 20:58:39 +0000</pubDate>
      <link>https://dev.to/dmahely/all-about-closures-2376</link>
      <guid>https://dev.to/dmahely/all-about-closures-2376</guid>
      <description>&lt;p&gt;I know what you're about to say. I, too, have read dozens of posts on JavaScript closures. But closures haven't really clicked for me until I read the MDN page three times then attempted to explain the concept to my mentor, &lt;a class="mentioned-user" href="https://dev.to/tryggvigy"&gt;@tryggvigy&lt;/a&gt;. Everything I learned from our conversation is written below.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a closure
&lt;/h2&gt;

&lt;p&gt;One of the reasons I couldn't get a good grasp on closures is because they don't mean anything to me in a regular context. In plain English, a closure is the process or act of closing something, and what am I gonna close in JavaScript except for my editor when I get one too many &lt;code&gt;undefined is not a function&lt;/code&gt; errors?&lt;/p&gt;

&lt;p&gt;People have different ways of explaining what a closure is. The short version is that a closure is a function's ability to access variables that are defined outside of it. If we have a function B inside another function A, any variables that are defined in function A can be accessed by function B.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;A&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;B&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; plus &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; equals &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;span class="nc"&gt;A&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above will log "1 plus 1 equals 2". This snippet calls function B inside of function A, so that function B executes whenever function A is called, such as in the last line.&lt;/p&gt;

&lt;p&gt;A useful attribute of closures is that they create variables that are private to a function. For example, the variable &lt;code&gt;one&lt;/code&gt; cannot be accessed outside of function A. This encourages us to declare variables only in the scope we need them in, and avoid unnecessary global variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Naming
&lt;/h2&gt;

&lt;p&gt;Now that we understand what closures are, why did they choose to call them that? Some people say that function A &lt;em&gt;closes over&lt;/em&gt; function B, since it is effectively protecting it from being read elsewhere in the code.&lt;/p&gt;

&lt;p&gt;And that's it for closures! But we can go a little bit further and relate them to two more concepts in JavaScript that are very closely related: higher order functions and lexical scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Higher order functions
&lt;/h2&gt;

&lt;p&gt;Most examples I've seen online will not look like the previous one, but will instead utilize higher order functions. A higher order function is a function that returns another function. Since higher order functions include outer and inner functions by definition, this means that every higher order function uses closures. However, not every function that has a closure is a higher order function, like we saw in the first example. The same snippet can be rewritten to use higher order functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;A&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;B&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; plus &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; equals &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;A&lt;/span&gt;&lt;span class="p"&gt;()();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, using &lt;code&gt;A()&lt;/code&gt; will return the body of function B, so we're using &lt;code&gt;A()()&lt;/code&gt; in order to execute function B.&lt;/p&gt;

&lt;p&gt;I'm using ES5 syntax but all of these concepts exist in ES6 as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; plus &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; equals &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;A&lt;/span&gt;&lt;span class="p"&gt;()();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lexical scope
&lt;/h2&gt;

&lt;p&gt;The other concept is lexical scope. I'm not even sure what lexical means, but in JavaScript, a function's scope starts from its opening curly bracket and ends with its closing bracket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7w41ol275dg2x9sgfg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7w41ol275dg2x9sgfg0.png" alt="Code example showing local and lexical scopes of functions A and B"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The innermost white bracket in the image is the local scope of function B. The middle red bracket is the local scope of function A, and the identical green line is the &lt;em&gt;lexical&lt;/em&gt; scope of function B. &lt;/p&gt;

&lt;p&gt;That's because the lexical scope of a function is the function's own local scope plus the local scope of its surrounding function(s). This means that the local scope of an outer function equals the lexical scope of an inner function. &lt;/p&gt;

&lt;p&gt;Now we can rewrite our definition of closures from &lt;em&gt;a function's ability to access variables declared outside of it&lt;/em&gt; to &lt;em&gt;a function's ability to access variables in its lexical scope&lt;/em&gt;. Some definitions even equate a closure with the function's lexical scope.&lt;/p&gt;

&lt;p&gt;Every function has a closure and lexical scope, even if it doesn't have a visible outer function. For instance, in front-end JavaScript, any function that you write has access to the global &lt;code&gt;window&lt;/code&gt; variable because it's in its lexical scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A closure is a function's ability to access variables declared outside of it (or in its lexical scope)&lt;/li&gt;
&lt;li&gt;By definition, all higher order functions use closures&lt;/li&gt;
&lt;li&gt;Lexical scope of a function is the function's local scope plus the local scope of any surrounding functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading! Until next time 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@pawel_czerwinski?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Paweł Czerwiński&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Module Management in Node</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Sun, 10 Jan 2021 17:46:29 +0000</pubDate>
      <link>https://dev.to/dmahely/module-management-in-node-3inp</link>
      <guid>https://dev.to/dmahely/module-management-in-node-3inp</guid>
      <description>&lt;p&gt;I regularly work with a Node project at work where functionality in a certain file is imported in other files using the &lt;code&gt;require&lt;/code&gt; keyword, and exported to be used in other files using the &lt;code&gt;module.exports&lt;/code&gt; keyword. More recently, I started working on a side project using create-react-app, where files are imported using the &lt;code&gt;import&lt;/code&gt; keyword and exported using the &lt;code&gt;export&lt;/code&gt; keyword. Although both projects use the same programming language, I never questioned this difference until now.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a module?
&lt;/h2&gt;

&lt;p&gt;To make code more DRY, we're often told to extract code that is used in many places to a separate function that is imported in all the files that need it. For example, a date parsing function that is used application-wide. In JavaScript speak, this function would be called a module. A module, however, isn't always necessarily a function, but can also be a number of related functions, a class or even a single variable. &lt;/p&gt;

&lt;h2&gt;
  
  
  Node's solution
&lt;/h2&gt;

&lt;p&gt;Node's module management system is called CommonJS, and it uses the aforementioned &lt;code&gt;require&lt;/code&gt; keyword. For example, here's a very simple function that checks token validity on a fetch request. The last line allows us to export this module to be used in other places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils/isTokenValid.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is how we'd use it in another file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils/isTokenValid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isTokenValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authentication error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  And then came ES6
&lt;/h2&gt;

&lt;p&gt;With this revision of the language, a native module management system was introduced. Now, we can rewrite the above example in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// utils/isTokenValid.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;isTokenValid&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils/isTokenValid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isTokenValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authentication error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example uses a default export for &lt;code&gt;isTokenValid&lt;/code&gt;. Alternatively, it can be rewritten as &lt;code&gt;export { isTokenValid }&lt;/code&gt; then imported in &lt;code&gt;index.js&lt;/code&gt; as &lt;code&gt;import { isTokenValid } from '../utils/isTokenValid'&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using &lt;code&gt;import/export&lt;/code&gt; in Node
&lt;/h2&gt;

&lt;p&gt;Now does that mean we have to remember where to use each of these two syntaxes if we're building a full stack JavaScript application? Thankfully, Node is already on it and has started to offer support to ES6 import/export syntax. At the moment, the support is &lt;a href="https://nodejs.org/api/esm.html#esm_modules_ecmascript_modules"&gt;experimental and unstable&lt;/a&gt; and therefore not recommended to be used in production. Using it is not straightforward either, as you have to change each file from a &lt;code&gt;.js&lt;/code&gt; to a &lt;code&gt;.mjs&lt;/code&gt; along with changes in your &lt;code&gt;package.json&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The other way to get started using import/export in your Node app is to install Babel which can take care of transpiling all your ES6 code to ES5. Personally, I opted to keep using CommonJS syntax in my backend and ES6 syntax in my frontend, now that I understand the difference between them.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Until next time 👋&lt;br&gt;
&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@dannylines"&gt;Danny Lines&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I deployed a full stack React/Express app to production</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Mon, 28 Dec 2020 18:52:46 +0000</pubDate>
      <link>https://dev.to/dmahely/how-i-deployed-a-full-stack-react-express-app-to-production-4216</link>
      <guid>https://dev.to/dmahely/how-i-deployed-a-full-stack-react-express-app-to-production-4216</guid>
      <description>&lt;p&gt;I recently &lt;a href="https://dev.to/dmahely/introducing-artest-a-music-quiz-game-3lf"&gt;launched&lt;/a&gt; a &lt;a href="https://artestgame.com" rel="noopener noreferrer"&gt;web application&lt;/a&gt; that consisted of a React frontend that communicated with an Express server. It was my first time working with this stack and everything worked smoothly on my local, but then came the time for deployment. &lt;em&gt;Cue the ominous music&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There are many many articles and tutorials on how to deploy this kind of app to production, to the point where I decided not to follow any of them and make up my own way. I had been wanting to practice using AWS so all the services used here are on that platform. I'm not claiming this is the best way but it's just what worked for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Domain name registered on Route 53&lt;/li&gt;
&lt;li&gt;React frontend deployed to Amplify&lt;/li&gt;
&lt;li&gt;Express backend hosted on a Lightsail instance&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Deploying the Frontend
&lt;/h1&gt;

&lt;p&gt;Amplify is an AWS service for hosting SPAs. It connects directly with your GitHub or GitLab repository, has continuous deployment set up on each push on master, and is totally free. It also has other awesome services such as deploying test branches, or generating preview builds when a PR is created. &lt;/p&gt;

&lt;p&gt;Start by navigating to the Amplify console in AWS and click on the &lt;em&gt;Connect App&lt;/em&gt; button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnexqbj5ket2afwalzsi8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnexqbj5ket2afwalzsi8.png" alt="Getting started with the Amplify console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After selecting your code hosting provider, Amplify will ask for read-only access to your account and you can go on with selecting a repo and a branch to deploy from.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu4rzj5foqxqdlsurv23h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu4rzj5foqxqdlsurv23h.png" alt="Add a repository branch on Amplify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Afterwards, you'll be asked to verify the build process generated for you, and soon enough your app will be live! 🙌 Amplify's generated URLs follow this format &lt;code&gt;branchName.randomCharacters.amplifyapp.com&lt;/code&gt;, so your website URL may look something like this &lt;a href="https://master.d1dgz538iqckwr.amplifyapp.com/" rel="noopener noreferrer"&gt;https://master.d1dgz538iqckwr.amplifyapp.com/&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In my code I was using an environment variable, and I was confused on how Amplify will be able to read it since the &lt;code&gt;.env&lt;/code&gt; file was in &lt;code&gt;.gitignore&lt;/code&gt; and therefore not committed, and I had no way to access the server on which the app is hosted. Then my eye caught the side menu where &lt;em&gt;Environment Variables&lt;/em&gt; is written. Here, I was able to add the key and value pair for my environment variable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvkaxpbolst5zvp3ck9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvkaxpbolst5zvp3ck9v.png" alt="Environment variables on Amplify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Updating environment variables requires redeploying the site, so go back to the app page and click on any of the steps shown in green. This will show you your build history and related data, plus a &lt;em&gt;redeploy this version&lt;/em&gt; button which you should click. Now, your deployed app can use the environment variable you specified. 👏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F68pl11nmox69yee92s1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F68pl11nmox69yee92s1u.png" alt="Application build pipeline on Amplify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another great thing about using Amplify is that you get an SSL certificate installed on your website and automatic redirection from HTTP to HTTPS.&lt;/p&gt;

&lt;h1&gt;
  
  
  Registering the Domain Name
&lt;/h1&gt;

&lt;p&gt;Route 53 is a DNS service offered by AWS that integrates nicely with Amplify. It allows you to get your own domain name and connect it to your deployed app easily.&lt;/p&gt;

&lt;p&gt;First, go to the Route 53 page in the AWS console, where you'll see the following component letting you know that you can create a new domain or transfer an existing domain into Route 53. In my case, I needed a brand new domain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcbdppz5ue2eazcwmjpj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcbdppz5ue2eazcwmjpj7.png" alt="Register domain form in Route 53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just type in the domain name you'd like to have and you'll get a list of all the available options with prices, plus some related suggestions. Once you settle on a domain, add it to your cart and check out. You'll be asked for your contact details for verification.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv04nmpojgo3s5xar3ekc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv04nmpojgo3s5xar3ekc.png" alt="Available domain names in Route 53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go back on your application in the Amplify console, click on &lt;em&gt;Domain Management&lt;/em&gt; in the side menu, and you'll be able to see the &lt;em&gt;Add domain&lt;/em&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu8z2ul6v4dizh4ejvxfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu8z2ul6v4dizh4ejvxfs.png" alt="Domain management in Amplify"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the domain name takes a while to get set up, and you'll get an email when it's finished. Mine was ready in about 15 minutes. A glass of water and some stretches later, visit your domain name to see your deployed frontend application. 🥳&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying the Backend
&lt;/h1&gt;

&lt;p&gt;There are a lot of options for deploying an Express backend. I wanted to try out serverless but I found it too complex. I saw a lot of tutorials using EC2 because it's included in the free tier, but it also requires a lot more setup. I opted to use AWS Lightsail which is a lightweight version of EC2 that lets you spin up virtual servers in no time. &lt;/p&gt;

&lt;p&gt;Simply navigate to the Lightsail console in AWS console, and click on &lt;em&gt;Create instance&lt;/em&gt;. Here, you'll need to pick an operating system for your server, a geographical region and a blueprint. The blueprint is a preconfigured image already set up to run your applications. I selected a Node.js blueprint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0vgizdm9s81atsmo75ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0vgizdm9s81atsmo75ik.png" alt="Available blueprints in Lightsail"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I chose the smallest instance size, with a memory of 512MB, 1 virtual CPU and 20GB of SSD storage. All of this comes at a cost of $3.50 a month, with the first month being offered for free. After your instance is created, you'll be able to see it in the Lightsail console. &lt;/p&gt;

&lt;p&gt;Chances are your Express application is running on a custom port like ports 3000 or 4000. All of these ports are closed by default to protect the instance. You can open custom ports by clicking on the three vertical dots in the instance component and clicking on &lt;em&gt;Manage&lt;/em&gt; then clicking on the &lt;em&gt;Networking&lt;/em&gt; tab. In this page, you can attach a static IP address for your instance for free, so that the IP address doesn't keep changing every time the instance is rebooted or taken down and restarted. A little further down under &lt;em&gt;Firewall&lt;/em&gt;, you can add a rule to open up your port to all IP addresses.&lt;/p&gt;

&lt;p&gt;Now that the server is set up and accessible on the internet on the specified port of the attached static IP address, you can ssh into it and get your application code. Lightsail allows ssh via a browser terminal, but you can also download the private key from your account page and use your own local terminal. After logging into the server, I cloned the backend repo from GitHub, installed dependencies then reloaded the sever. I used PM2 as a process manager. Now my endpoints are accessible on the internet! 🎊 I also went back into the Route 53 to add an A record to my hosted zone to have a subdomain for my backend: &lt;a href="https://api.example.com" rel="noopener noreferrer"&gt;https://api.example.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This setup means that whenever I make changes in the code, I have to ssh into the server, run &lt;code&gt;git pull&lt;/code&gt; and &lt;code&gt;pm2 reload app&lt;/code&gt;, which is too manual for my liking. I looked into GitHub Actions that continuously deploy to Lightsail instances but didn't find any good options. I'm fine with keeping it like this for the moment, since I know my backend repo won't have a lot of changes.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Connecting the two
&lt;/h1&gt;

&lt;p&gt;When I was developing on my local, I had a &lt;code&gt;proxy&lt;/code&gt; option added in &lt;code&gt;package.json&lt;/code&gt; in my frontend. It was hardcoded to the value of my backend url, and after a bit of research it seemed that replacing the hardcoded value with an environment variable was too much of a hassle. Instead, I removed the proxy option and added the environment variable in each &lt;code&gt;fetch&lt;/code&gt; request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_BACKEND_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/token`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, my frontend is live and has the URL for my backend which is also live, so they should be able to talk to each other, right? Not so fast! My frontend was being served over HTTPS while my backend was served over HTTP. The browser rightly didn't allow me to make a request from a secure domain to an insecure one. &lt;/p&gt;

&lt;p&gt;With bitnami, you can install an SSL certificate on your server for free with one command: &lt;code&gt;sudo /opt/bitnami/bncert-tool&lt;/code&gt;. More info on that &lt;a href="https://docs.bitnami.com/aws/how-to/generate-install-lets-encrypt-ssl/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This tool also lets you enable automatic HTTP to HTTPS redirection. After this step, I could type in my server URL with an HTTP and see it get resolved into an HTTPS on the browser. &lt;/p&gt;

&lt;p&gt;At this point, I reloaded my frontend via the Amplify console to try to get the API requests going. In the browser's network tab, I was able to see that the request is going to the correct URL: &lt;a href="https://api.example.com:4000/" rel="noopener noreferrer"&gt;https://api.example.com:4000/&lt;/a&gt;, but my request is failing without even reaching the server! On a closer look, I noticed the error shown next to the &lt;em&gt;failed&lt;/em&gt; status: &lt;code&gt;NET::ERR_SSL_PROTOCOL_ERROR&lt;/code&gt;. Here I realized that I've been trying to access a custom port using the HTTPS protocol. &lt;/p&gt;

&lt;p&gt;I thought of a couple of options: either run my Express server on port 443 to be served over HTTPS, or somehow make my custom port be served over HTTPS.  After checking out a lot of &lt;a href="https://dev.to/dmahely/pm2-listening-on-port-443-shows-eaddrinuse-address-already-in-use-443-1aho"&gt;options&lt;/a&gt;, I was able to get it working by setting up the Apache virtual host to redirect all traffic from ports 80 and 443 to port 4000. &lt;/p&gt;

&lt;p&gt;Finally, my full stack application was truly up and running! 🎉 If you're curious what the application is, check out my &lt;a href="https://dev.to/dmahely/introducing-artest-a-music-quiz-game-3lf"&gt;announcement post&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thanks for reading 👋 Until next time.&lt;br&gt;
&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@marxgall?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Marek Szturc&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing Artest: a music quiz game 👩‍🎤</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Mon, 21 Dec 2020 21:12:56 +0000</pubDate>
      <link>https://dev.to/dmahely/introducing-artest-a-music-quiz-game-3lf</link>
      <guid>https://dev.to/dmahely/introducing-artest-a-music-quiz-game-3lf</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftxujv3riq8y4g09f9lgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftxujv3riq8y4g09f9lgn.png" alt="Artest logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm happy to launch my new side project today 🎉 &lt;a href="https://artestgame.com" rel="noopener noreferrer"&gt;Artest&lt;/a&gt; is a music quiz game that challenges players to guess the artists by showing them a bunch of random album covers. Features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecting how many rounds to play 🎱&lt;/li&gt;
&lt;li&gt;Getting musical trivia after each round 👁&lt;/li&gt;
&lt;li&gt;Hundreds of albums and artists as questions 👩‍🎤&lt;/li&gt;
&lt;li&gt;Sharing results to social media 📲&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I started this project as a way to improve my front-end skills, specifically with UI design and React. It was supposed to be a simple project but it kept growing bigger, and with the support of my awesome mentor &lt;a href="https://dev.to/tryggvigy"&gt;@tryggvigy&lt;/a&gt; I ended up learning tons. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv49ym7coo3mvi4oygq0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv49ym7coo3mvi4oygq0z.png" alt="Round screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Development process
&lt;/h2&gt;

&lt;p&gt;Being a developer more comfortable in the backend, I usually start my side projects with hooking up to whatever API I needed and rendering that on the screen. I would only do the bare minimum to make the UI look presentable. This time however, I took the complete opposite route by starting with design, then building the frontend components and then finally working on the APIs and backend to get actual data.&lt;/p&gt;

&lt;p&gt;I started the design phase in the beginning of August, and ended up catching the design bug. I spent hours on Dribbble being inspired by artists and designers and tweaking my own wireframes. Starting with designing the UI allowed me to think of the functionality I wanted and how I would build it. I made three pretty different designs and settled on the cleanest one.&lt;/p&gt;

&lt;p&gt;Only when the design phase was finished, I started creating the React components with dummy data. I tried to keep as close as possible to the design. I started with a create-react-app template and had the frontend call the Spotify APIs directly. However, create-react-app doesn't allow for truly secret environment variables, and I didn't want my Spotify credentials to be exposed. At this point, the game was playable and could've been deployed as is, but even though this is a small side project I didn't want to compromise on security.&lt;/p&gt;

&lt;p&gt;Therefore, I decided to build my own Express backend and refactor the frontend to call my APIs that will in turn call the Spotify APIs. This was definitely the biggest refactor I did in this project, and probably ever. Here is the git diff for that PR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6x651diw5c5g20zrygdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6x651diw5c5g20zrygdn.png" alt="Git diff showing +51 and -1,537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I spent some time afterwards learning about and writing unit tests, and finally when most of the bugs were squashed and the game was playable in my local, I set about in deploying the application to production. This part warrants a full-length post but I ended up using AWS. I spent the last couple of weeks tweaking and manually testing the site on my own.&lt;/p&gt;

&lt;p&gt;The code is all open source and available on my GitHub, so take a look if you're interested. The frontend repo is &lt;a href="https://github.com/dmahely/artest.git" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the backend repo is &lt;a href="https://github.com/dmahely/artest-backend.git" rel="noopener noreferrer"&gt;here&lt;/a&gt; ⭐️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1nm8loxmtebxl9b249o4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1nm8loxmtebxl9b249o4.png" alt="Round result screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;This has been an incredible learning opportunity for me. Throughout this project, I worked on all kinds of different things I didn't have a chance to use before. That includes UI design, writing unit tests, using ES6 classes and deploying a full stack application to production. I used CSS variables, React hooks, the Fetch API, ESLint, Prettier and Jest. I owe a lot of thanks to my mentor Tryggvi whose help has been invaluable!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc345ey29wb735nuroohg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc345ey29wb735nuroohg.png" alt="Final result screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I still have a lot of ideas that I want to implement with Artest including adding hints and a leaderboard, and I welcome and appreciate your feedback!&lt;/p&gt;

&lt;p&gt;Thanks for reading 👋 Until next time.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>react</category>
      <category>express</category>
    </item>
    <item>
      <title>PM2 listening on port 443 shows EADDRINUSE: address already in use :::443</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Mon, 09 Nov 2020 16:34:28 +0000</pubDate>
      <link>https://dev.to/dmahely/pm2-listening-on-port-443-shows-eaddrinuse-address-already-in-use-443-1aho</link>
      <guid>https://dev.to/dmahely/pm2-listening-on-port-443-shows-eaddrinuse-address-already-in-use-443-1aho</guid>
      <description>&lt;p&gt;I have a Node/Express app running on an AWS Lightsail instance with PM2 as a process manager. The app is currently running on port 4000. The IP address for the instance is attached to a subdomain that has a valid SSL certificate and automatically redirects from HTTP to HTTPS. Visiting &lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt; at the moment shows the 'Congratulations! You are now running Bitnami Node.js 12.18.3 in the Cloud.' page. &lt;/p&gt;

&lt;p&gt;Currently, all the Express endpoints are only accessible through &lt;a href="http://example.com:4000/endpoint" rel="noopener noreferrer"&gt;http://example.com:4000/endpoint&lt;/a&gt;, but I want the Express app to run on port 443 so that the endpoints are accessible immediately on &lt;a href="https://example.com/endpoint" rel="noopener noreferrer"&gt;https://example.com/endpoint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I read that PM2 is able to listen on ports 80 and 443 and tried the method mentioned in the &lt;a href="https://pm2.keymetrics.io/docs/usage/specifics/#listening-on-port-80-w-o-root" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, but whenever I change the port number in the .env file to 443 and reload the app using &lt;code&gt;pm2 reload app&lt;/code&gt;, I get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0|app    | Error: listen EADDRINUSE: address already in use :::443
0|app    |     at Server.setupListenHandle [as _listen2] (net.js:1313:16)
0|app    |     at listenInCluster (net.js:1361:12)
0|app    |     at Server.listen (net.js:1447:7)
0|app    |     at Function.listen (/opt/bitnami/apache/htdocs/node_modules/express/lib/application.js:618:24)
0|app    |     at Object.&amp;lt;anonymous&amp;gt; (/opt/bitnami/apache/htdocs/app.js:44:5)
0|app    |     at Module._compile (internal/modules/cjs/loader.js:1137:30)
0|app    |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
0|app    |     at Module.load (internal/modules/cjs/loader.js:985:32)
0|app    |     at Function.Module._load (internal/modules/cjs/loader.js:878:14)
0|app    |     at Object.&amp;lt;anonymous&amp;gt; (/opt/bitnami/node/lib/node_modules/pm2/lib/ProcessContainerFork.js:33:23) {
0|app    |   code: 'EADDRINUSE',
0|app    |   errno: 'EADDRINUSE',
0|app    |   syscall: 'listen',
0|app    |   address: '::',
0|app    |   port: 443
0|app    | }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;App.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// for parsing POST bodies&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`🥁 App listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.env&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of &lt;code&gt;pm2 status&lt;/code&gt; at the moment:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhpjf14ei44tqxv9i2lvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhpjf14ei44tqxv9i2lvh.png" alt="aSXDK"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any help would be appreciated! &lt;/p&gt;

</description>
      <category>help</category>
      <category>node</category>
      <category>pm2</category>
    </item>
    <item>
      <title>3 simple steps to connect your Express and React apps</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Fri, 06 Nov 2020 20:42:03 +0000</pubDate>
      <link>https://dev.to/dmahely/3-simple-steps-to-connect-your-express-and-react-apps-obp</link>
      <guid>https://dev.to/dmahely/3-simple-steps-to-connect-your-express-and-react-apps-obp</guid>
      <description>&lt;p&gt;Having your frontend and backend in two separate repositories rather than combining both is a common enough pattern. Follow the steps below to connect your React project that is running on port 3000 with your Express server that is running on port 4000.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Add a proxy in your frontend
&lt;/h2&gt;

&lt;p&gt;In your React app, open up &lt;code&gt;package.json&lt;/code&gt; and add the following line anywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// React app, package.json&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;proxy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:4000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will let your React app know that when you do fetches that look like they're for resources on the same server, for example &lt;code&gt;fetch('/')&lt;/code&gt;, it will look for that endpoint on the proxy server you specified, i.e. your Express server.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add an API endpoint
&lt;/h2&gt;

&lt;p&gt;Add an example endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Express repo, app.js&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And an example fetch request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// React repo, src/App.js&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;responseVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;fetchResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Try it out!
&lt;/h2&gt;

&lt;p&gt;Start up both servers in localhost. Again, your React app will run on port 3000 and your Express server will be on port 4000.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzw5xeutmwh8m3fg2jzx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzw5xeutmwh8m3fg2jzx2.png" alt="React app in localhost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftuqag4unm4ca3qt96vv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftuqag4unm4ca3qt96vv2.png" alt="Express app in localhost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the &lt;code&gt;fetch&lt;/code&gt; method is wrapped in a &lt;code&gt;useEffect&lt;/code&gt;, it will run as soon as the React server starts and the page is rendered. You can now open up the console in the frontend and see that the pinged endpoint's response is being logged correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F41byuzeidtsxhs7x40xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F41byuzeidtsxhs7x40xj.png" alt="Console showing hello world"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common issues
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you see "You need to enable JavaScript to run this app" as a response, chances are you forgot to add the proxy in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the browser network tab shows that the url specified in the &lt;code&gt;fetch&lt;/code&gt; doesn't exist (a 404 error), try replacing localhost with 127.0.0.1 as the proxy value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it's anything else, write it down in the comments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading! Until next time 👋&lt;br&gt;
&lt;em&gt;Cover photo by Hans-Peter Gauster on &lt;a href="https://unsplash.com/s/photos/connection?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>express</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Using Moment's isBetween()</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Fri, 16 Oct 2020 12:21:30 +0000</pubDate>
      <link>https://dev.to/dmahely/using-moment-s-isbetween-p6c</link>
      <guid>https://dev.to/dmahely/using-moment-s-isbetween-p6c</guid>
      <description>&lt;p&gt;&lt;em&gt;This post uses Moment.js version 2.29.1. Moment.js is currently considered to be in maintenance mode and isn't encouraged to be used in new projects. More &lt;a href="https://momentjs.com/docs/#/-project-status/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This week I was working on a cron job that pulls data from an external API to check if any values were added in the last 10 minutes. The API didn't allow filtering by time, so I had to pull all the data that was added that day, then go over them and check if any values were added in the last 10 minutes. &lt;/p&gt;

&lt;p&gt;Working with dates and time is always tricky, and this was no exception. For this feature, I opted to use Moment.js over native JavaScript because it's easier to read and it was already a dependency. Let's say we want to appreciate anyone who takes the time to comment on our posts. The example I'll use will get all comments made today, then filter them out to return the comments made in the last 10 minutes so we can like them or reply to them with an emoji 🦄.&lt;/p&gt;

&lt;p&gt;We'll start with creating the function and defining the format that the comments' dates and times are returned in from the API.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLatestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M/DD/YYYY hh:mm:ss A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We will need two other variables, the start time and end time we'll be filtering between. The start time will be the current date and time minus 10 minutes, and the end time will just be the current date and time.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLatestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M/DD/YYYY hh:mm:ss A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;minutes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now minus 10 minutes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can use &lt;code&gt;moment()&lt;/code&gt; only to get the current date and time, but with calling &lt;code&gt;format()&lt;/code&gt; on it, we can get a neatly formatted string back instead of the entire moment object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr3lc9kuukvk1pggbozdo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr3lc9kuukvk1pggbozdo.png" alt="Using moment() will return an object while using moment().format() will return a string"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, let's see how we can check if the comment's date and time is between our two variables. Moment.js has &lt;a href="https://momentjs.com/docs/#/query/is-between/" rel="noopener noreferrer"&gt;this&lt;/a&gt; handy function named &lt;code&gt;isBetween()&lt;/code&gt; that returns a boolean. This method takes two &lt;em&gt;moment-like objects&lt;/em&gt; as parameters, where a moment-like object can be a moment object, string, number, date or array. In our case, we'll be using the strings we created above. It's worth noting that this function is exclusive by default, but accepts an additional parameter to specify inclusivity. &lt;/p&gt;

&lt;p&gt;The next natural step for me was to do something like this, where I first create a moment object of each comment's publishing date and time, then format it as I did with the previous variables:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLatestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M/DD/YYYY hh:mm:ss A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;minutes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now minus 10 minutes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But here, we'll start to notice two things in the console:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// console&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.

TypeError: moment(comment.dateTime).format().isBetween is not a function. (In 'moment(comment.time).format().isBetween(start, end)', 'moment(comment.dateTime).format().isBetween' is undefined)


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is because Moment.js doesn't know what format the date and time we're passing it is in, so it's not able to reformat it. We can easily fix this by passing the format the comment's date and time will be in. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Notice how I removed the subsequent &lt;code&gt;format()&lt;/code&gt;, and that's because the &lt;code&gt;format()&lt;/code&gt; function returns a string, while &lt;code&gt;moment()&lt;/code&gt; returns an object, and we need an object so we can call the &lt;code&gt;isBetween()&lt;/code&gt; function on it. So this is what our complete function will look like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLatestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M/DD/YYYY hh:mm:ss A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;minutes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now minus 10 minutes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// now&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todayComments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isBetween&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;latestComments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Assuming that today is the 16th of October, 2020 and the current time is 12:10 PM, let's see our function in action.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// example input&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I would love to do something similar in my website.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Barbara&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10/16/2020 12:04:13 PM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Great job!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10/16/2020 12:01:07 PM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Keep up the good work 😊&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10/16/2020 11:57:55 AM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getLatestComments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latestComments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// output &lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I would love to do something similar in my website.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Barbara&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10/16/2020 12:04:13 PM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Great job!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10/16/2020 12:01:07 PM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Thanks for reading! Until next time 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@heatherz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Heather Zabriskie&lt;/a&gt; on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>momentjs</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What is a polyfill?</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Fri, 02 Oct 2020 14:17:14 +0000</pubDate>
      <link>https://dev.to/dmahely/what-is-a-polyfill-383l</link>
      <guid>https://dev.to/dmahely/what-is-a-polyfill-383l</guid>
      <description>&lt;p&gt;If you're like me, chances are you heard the word &lt;strong&gt;polyfill&lt;/strong&gt; used before in a context where it wasn't easy to deduce a meaning. Thanks to my new tendency of writing down things I'd like to learn about and a subsequent discussion with &lt;a class="mentioned-user" href="https://dev.to/tryggvigy"&gt;@tryggvigy&lt;/a&gt;
, I was able to get a better understanding of what polyfills are. &lt;/p&gt;

&lt;p&gt;A polyfill is code that acts as a backup when certain properties, functions or syntax aren't supported in a browser or environment. It's not language-specific, although I've seen it mostly used with JavaScript and CSS. If that doesn't make sense, let's look at MDN's definition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A polyfill is a piece of code (usually JavaScript on the Web) used to provide modern functionality on older browsers that do not natively support it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;New features are never supported on all browsers out of the box. Imagine wanting to refactor your code to use new ES2019 features such as the nullish coalescing operator or &lt;code&gt;Array.prototype.flatMap&lt;/code&gt;. In this case, your code will break because older browsers will not recognize it as valid JavaScript. A polyfill can provide a backup in this case to ensure new features are backward-compatible.&lt;/p&gt;

&lt;p&gt;Let's take a closer look with the example code from MDN's page on the nullish coalescing operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// expected output: "default string"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// expected output: 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's try running it on Safari 13.0 &lt;em&gt;(currently not supported)&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SyntaxError: Unexpected token '?'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the time of writing, the &lt;code&gt;??&lt;/code&gt; operator is supported for &lt;strong&gt;77.08%&lt;/strong&gt; of global users. If you're using it in production, you're ignoring a very big slice of potential users. To work around this, you can search for a &lt;code&gt;??&lt;/code&gt; polyfill and add it to your code so that the new syntax will work with supported browsers, and the polyfill will work for the older unsupported browsers. &lt;/p&gt;

&lt;p&gt;Thankfully, you don't actually need to go out and search for polyfills and manually add them to your codebase. Babel is an example of a tool (also referred to as a compiler, transpiler or transcompiler) that enables us to write the newest and latest JavaScript syntax without having to worry about keeping track of polyfills. &lt;/p&gt;

&lt;p&gt;With Babel installed in our codebase, we can write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and have it automatically be converted to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;_object$foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_object$foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;_object$foo&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;_object$foo&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another interesting example is the polyfill for &lt;code&gt;Array.prototype.map&lt;/code&gt; which can be found &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Polyfill"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To end with, it's worth mentioning that using polyfills exclusively, as opposed to browsers and environments working to natively support new features, is not a good idea for performance and functionality reasons.&lt;/p&gt;

&lt;p&gt;Thank you for reading. Until next time 👋&lt;br&gt;
&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@teckhonc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;T.H. Chia&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Polyfill"&gt;https://developer.mozilla.org/en-US/docs/Glossary/Polyfill&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://caniuse.com/mdn-javascript_operators_nullish_coalescing"&gt;https://caniuse.com/mdn-javascript_operators_nullish_coalescing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://babeljs.io/docs/en/babel-plugin-proposal-nullish-coalescing-operator"&gt;https://babeljs.io/docs/en/babel-plugin-proposal-nullish-coalescing-operator&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Refactoring every .forEach to a .map</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Fri, 25 Sep 2020 16:19:35 +0000</pubDate>
      <link>https://dev.to/dmahely/refactoring-every-foreach-to-a-map-3mej</link>
      <guid>https://dev.to/dmahely/refactoring-every-foreach-to-a-map-3mej</guid>
      <description>&lt;p&gt;I often read JavaScript articles and noticed that many of them focus heavily on &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt;, more so than other array methods. In my current React project, I noticed that I've used &lt;code&gt;map&lt;/code&gt; more but also that I unconsciously used &lt;code&gt;forEach&lt;/code&gt; a bunch of times, so I decided to dig into it more.&lt;/p&gt;

&lt;p&gt;First, let's go over what we know about the two functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;.forEach&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Goes over the array it is called on and executes the callback function on each element&lt;/li&gt;
&lt;li&gt;Changes the original array&lt;/li&gt;
&lt;li&gt;Returns undefined
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MDN's example&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;array1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// expected output: "a"&lt;/span&gt;
&lt;span class="c1"&gt;// expected output: "b"&lt;/span&gt;
&lt;span class="c1"&gt;// expected output: "c"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;.map&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Goes over the array it is called on and executes the callback function on each element&lt;/li&gt;
&lt;li&gt;Does not change the original array&lt;/li&gt;
&lt;li&gt;Returns a new array with the result
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MDN's example&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;array1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// pass a function to map&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;array1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;map1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// expected output: Array [2, 8, 18, 32]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we saw, both functions &lt;strong&gt;do the exact same thing&lt;/strong&gt;, and both are supported in all browsers. However, the way they work under the hood differs. &lt;/p&gt;

&lt;h2&gt;
  
  
  Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Use cases
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;map&lt;/code&gt; returns a new array without mutating the original, so it makes sense to use it if we are planning to use the returned array elsewhere. However, if we don't mind mutating the original array and aren't planning to use it somewhere else, using &lt;code&gt;forEach&lt;/code&gt; is recommended. Per &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#When_not_to_use_map"&gt;MDN&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You shouldn't be using &lt;code&gt;map&lt;/code&gt; if you're not using the array it returns and/or you're not returning a value from the callback.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Approach
&lt;/h3&gt;

&lt;p&gt;Because of &lt;code&gt;map&lt;/code&gt;’s nature, people who prefer a more functional approach will lean towards it. Functional programming is an approach to building software by using pure functions that take an input and return an output. In functional programming, functions do not modify variables outside of their scope, state is not shared and data is never mutated. This approach greatly diminishes the number of bugs that may be introduced into your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Performance
&lt;/h3&gt;

&lt;p&gt;According to &lt;a href="https://codeburst.io/javascript-map-vs-foreach-f38111822c0f?gi=d9973392feeb"&gt;this&lt;/a&gt; post, &lt;code&gt;map&lt;/code&gt; seems to be much more performant than &lt;code&gt;forEach&lt;/code&gt;. However, I've since learned there's a big deal of controversy around this particular benchmark. It's not fair to compare the following two pieces of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;doubled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;since the &lt;code&gt;return&lt;/code&gt; statement in the first example serves no purpose. Moreover, the performance of these functions depends on the implementation of JavaScript engines in different browsers, so the comparison is not so cut-and-dried. &lt;/p&gt;

&lt;h3&gt;
  
  
  4. Asynchronous programming
&lt;/h3&gt;

&lt;p&gt;As stated by &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#forEach_expects_a_synchronous_function"&gt;MDN&lt;/a&gt;, &lt;code&gt;forEach&lt;/code&gt; expects its callback to be synchronous, so it won't play well with any fancy async code you may have. &lt;code&gt;map&lt;/code&gt; however will be more tolerant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring
&lt;/h2&gt;

&lt;p&gt;In my project, I was using &lt;code&gt;forEach&lt;/code&gt; to iterate over my rounds array, which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"rounds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"artists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Three Days Grace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IDK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have an array of strings that contains images of the current round's artists, and I wanted to iterate over each artist and add the image property to the object. This is how I first achieved that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;artistImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getArtistData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;artistData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns an array of strings&lt;/span&gt;
&lt;span class="nx"&gt;rounds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;artists&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentRound&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artistImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rounds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was calling this function in a component then assigning the returned array in state. Now, the state looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"rounds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"artists"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Three Days Grace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://i.scdn.co/image/2a9ec8d494f8d0a52fd67c3239efc2b9e79a4ced"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IDK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://i.scdn.co/image/6594334f1d1a2e65394d27eb457ccff203886411"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refactoring to use &lt;code&gt;map&lt;/code&gt; was quite simple and achieved the same result. It is exactly the same line of code, but now I'm returning something inside &lt;code&gt;map&lt;/code&gt; and saving it in a variable, then returning that variable to my component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;artistImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getArtistData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;artistData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns an array of strings&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roundsWithImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rounds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
   &lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;artists&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentRound&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artistImages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;roundsWithImages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now hopefully my code is a little more readable and the likelihood of me messing up due to mutated variables is a little smaller!&lt;/p&gt;

&lt;p&gt;Thank you for reading. Let me know how I can make this article better. Until next time 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@4themorningshoot?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Oliver Hale&lt;/a&gt; on Unsplash.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codequality</category>
    </item>
    <item>
      <title>The day our web server reached 100% capacity 💾</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Sun, 06 Sep 2020 19:07:02 +0000</pubDate>
      <link>https://dev.to/dmahely/the-day-our-web-server-reached-100-capacity-a56</link>
      <guid>https://dev.to/dmahely/the-day-our-web-server-reached-100-capacity-a56</guid>
      <description>&lt;h2&gt;
  
  
  How it began
&lt;/h2&gt;

&lt;p&gt;One day a few months back, the QA engineer texted me on Slack saying that he couldn't log into the web application. Naturally, I tried to login with his credentials and was able to. I thought he forgot his password, so I sent it to him and he said that he could login now. I didn't think anything of it.&lt;/p&gt;

&lt;p&gt;2 hours later, right about log off time, I get an email from a client saying they're not able to login. I dismissed it thinking they forgot their password, intending to get back to them first thing tomorrow. Then, a mobile developer on my team said the same thing. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/5t0xKpewtlRTvWgv64/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/5t0xKpewtlRTvWgv64/giphy.gif" alt="Smells a bit fishy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I get to investigating. I went to the website and tried to login and &lt;strong&gt;I couldn't&lt;/strong&gt;. The page would reload when I hit Enter without showing any errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/swrTFeuOt2v6g/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/swrTFeuOt2v6g/giphy.gif" alt="Wait what"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I quickly started debugging when a colleague mentioned it could be an issue with the database connection. We had recently moved from using a single database instance to a database cluster, and assumed this might be causing an issue or that one instance was taking on too much load. Since this change had been the biggest and most recent one, we narrowed our focus on it. However, the database console looked fine, and didn't show any extra load on any specific instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/mA1Q2gTm2Qibn7mdj8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/mA1Q2gTm2Qibn7mdj8/giphy.gif" alt="What does that mean"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This issue only happened on production, so it was safe to assume it was not related to any code changes. At this point, we started getting more and more complaints from clients, so I decided to do something dangerous: &lt;strong&gt;debug on production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Tvkxet8PY8KN4CBNGP/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Tvkxet8PY8KN4CBNGP/giphy.gif" alt="Buckle up"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I connected to the server using Cyberduck, navigated to the login view file and logged something like &lt;code&gt;logging in&lt;/code&gt;. To my surprise, when I hit save, the file didn't get saved. Cyberduck showed a vague error I can't remember and didn't understand at the time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/zkSFsZpQMZuG4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/zkSFsZpQMZuG4/giphy.gif" alt="Huh"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a couple more hours of debugging, we realized that the server has reached 100% disk usage. That day, I learned two useful unix commands: &lt;code&gt;du&lt;/code&gt; and &lt;code&gt;df&lt;/code&gt;. From the man page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;du&lt;/strong&gt; utility displays the file system block usage for each file argument and for each directory in the file hierarchy rooted in each directory argument.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;df&lt;/strong&gt; utility displays statistics about the amount of free disk space on the specified filesystem or on the filesystem of which file is a part.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This meant one thing: we had to upgrade the disk size. Thankfully my colleague figured out how to do that with no downtime. &lt;/p&gt;

&lt;p&gt;Crisis was averted. People were able to login.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3krrjoL0vHRaWqwU3k/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3krrjoL0vHRaWqwU3k/giphy.gif" alt="Phew"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The end... Not
&lt;/h2&gt;

&lt;p&gt;Believe it or not, but due to the immense workload we had at the time, no further action was taken to monitor the server disk space or dig deeper into why this happened. So somewhat unsurprisingly, two months later, the server reached 100% capacity &lt;em&gt;again&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;We were better prepared and quickly identified the issue and upgraded the disk size. This time around, I took the time to dig into why this happened, since we didn't upload a lot of files within the last two months that would justify filling up around ~90 Gigabytes.&lt;/p&gt;

&lt;p&gt;Again, I utilized the &lt;code&gt;du&lt;/code&gt; and &lt;code&gt;df&lt;/code&gt; commands to pinpoint the directory that's eating up the disk space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; /var
...
170.3G    /mail
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://i.giphy.com/media/RILsqUte1MME7TzQJ9/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/RILsqUte1MME7TzQJ9/giphy.gif" alt="Surprised"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine that, the mail directory was taking up 170 Gigabytes, almost 80% of the entire server's disk space! Further digging showed that the culprit was crontab. We had several cron jobs running, and crontab sends emails to the root user that get stored in &lt;code&gt;/var/mail&lt;/code&gt;. This was listed clearly in the crontab file as shown below, but the output of a particular cron job was returning a lot of junk that somehow managed to fill up the directory quite quickly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;crontab &lt;span class="nt"&gt;-l&lt;/span&gt;
...
&lt;span class="c"&gt;# Output of the crontab jobs (including errors) is sent through&lt;/span&gt;
&lt;span class="c"&gt;# email to the user the crontab file belongs to (unless redirected).&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Now what?
&lt;/h2&gt;

&lt;p&gt;The plan of action was to first stop further emails, then to delete the existing emails to free up the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="nv"&gt;MAILTO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="c"&gt;# to disable cron emails&lt;/span&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo rm&lt;/span&gt; /var/mail/ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Smarter and wiser, we figured let's set up a monitoring service to catch this particular issue in case it happens again. The service of choice was &lt;a href="https://mmonit.com/monit/"&gt;Monit&lt;/a&gt; and it was surprisingly easy to start using. It creates a dashboard that allows us to visualize all the numbers we need easily, from disk space to CPU usage to memory, and sends emails alerts on custom events. &lt;a href="https://www.alibabacloud.com/blog/how-to-install-monit-monitoring-tool-on-ubuntu-16-04_594339"&gt;This great article&lt;/a&gt; is very helpful in setting up Monit on an Ubuntu server. &lt;/p&gt;

&lt;p&gt;And the rest is history. We didn't face an issue with disk space again. &lt;em&gt;So far&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/2ALDrK4ckHNLNCw45v/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/2ALDrK4ckHNLNCw45v/giphy.gif" alt="So relieved"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! Until next time 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@tvick?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Taylor Vick&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>startup</category>
    </item>
    <item>
      <title>Remembering the difference between GET and POST 💡</title>
      <dc:creator>Doaa Mahely</dc:creator>
      <pubDate>Sun, 30 Aug 2020 18:14:39 +0000</pubDate>
      <link>https://dev.to/dmahely/remembering-the-difference-between-get-and-post-4cde</link>
      <guid>https://dev.to/dmahely/remembering-the-difference-between-get-and-post-4cde</guid>
      <description>&lt;p&gt;I was reminded recently of the difference between GET and POST requests, after joining a colleague of mine on a project that uses Express, while knowing exactly nothing about Express. I thought this write-up will serve as a good reminder of the differences between those two HTTP methods and how to use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going in blind
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ucXQyAst--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wq7sbjn72473f5l0ww1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ucXQyAst--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wq7sbjn72473f5l0ww1g.png" alt="Developer focusing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Being a learn-by-doing type, I got to work seeing the existing code and trying to follow along. My first task was to retrieve a user's profile details. This was obviously a GET method since we'll just be retrieving data and not creating anything new. I went to the &lt;code&gt;users&lt;/code&gt; route file and added the following endpoint &lt;code&gt;router.get('/profile', users.getProfile);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, I went to the &lt;code&gt;users&lt;/code&gt; controller and created the following &lt;code&gt;getProfile&lt;/code&gt; function, which was basically copied and pasted from an existing POST endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this function, we first get the user's id from the request's body, then pass it to the model which will check for it in the database and hopefully return some data to us. Next I tried to connect to this endpoint by providing a valid user id using Postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nOJAz4V4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m2whlvznlvxgbf6vzasv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nOJAz4V4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m2whlvznlvxgbf6vzasv.png" alt="Sending a GET request to /profile using Postman, on Body tab"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Notice how I'm sending data in the GET request's body, we'll come back to this later.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;and I got the following response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"050-5555555"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"full_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Live Laugh Love!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! 👏 Naturally, the next step is to show this data in the view layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when I refresh the page, this AJAX request should hit the endpoint we specified and log the data. Perhaps unsurprisingly, this logs &lt;em&gt;Invalid id&lt;/em&gt;. Let's try to send the id another way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/profile?id=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmmm, this also logs &lt;em&gt;Invalid id&lt;/em&gt;. Weird. At this point, and because I was in a hurry, I just changed the route method from GET to POST, and changed it in the AJAX request as well, and I started seeing a result in the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// changed to post&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// changed to post&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this worked and I was short on time, I moved on to other endpoints which incidentally were all retrieving data but ended up being written as POST requests. A couple of weeks later, I had some time off and I was still thinking about this behavior, so I decided to revise HTTP methods and properly learn Express.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bx-SvLDS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3atmnlobo9wpakj58wss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bx-SvLDS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3atmnlobo9wpakj58wss.png" alt="Lightbulb moment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I had forgotten was the main difference between GET and POST methods. Per MDN, GET requests should &lt;strong&gt;not&lt;/strong&gt; have a body. Instead, the data should be sent in the request URL, in contrast to POST requests which hide the data in the request body and are therefore more secure. This great example from freeCodeCamp illustrates the concept:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GET request using query strings&lt;/span&gt;
&lt;span class="nx"&gt;route_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;actual_request_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/library?userId=546&amp;amp;bookId=6754&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;546&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;6754&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// GET request using route parameters&lt;/span&gt;
&lt;span class="nl"&gt;route_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user/:userId/book/:bookId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;actual_request_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/user/546/book/6754&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;546&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bookId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;6754&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// POST request&lt;/span&gt;
&lt;span class="nl"&gt;route_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;actual_request_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;546&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, Postman allowed us to embed data in a GET request's body which caused the confusion. Let's see the correct way to pass data with a GET request in Postman.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g96dy02k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x1q2nlcd97qi8a45eqc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g96dy02k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x1q2nlcd97qi8a45eqc4.png" alt="Sending a GET request to /profile using Postman, on Params tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: make sure you're on the 'Params' tab instead of the 'Body' tab which I was on earlier. Force of habit!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E3UkdKyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zrrc02uyewiw8zk1upfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E3UkdKyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zrrc02uyewiw8zk1upfp.png" alt="Light the fire"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's refactor our function to use a GET request as it was intended to. First, let's turn back our AJAX request to use the GET method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// change this back to GET&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And update our route to use GET as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, on to our controller&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// use req.query, instead of req.body&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila! We're successfully getting a response in our AJAX GET request 🎉&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mobile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"050-5555555"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"full_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Live Laugh Love!"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GET requests &lt;strong&gt;do not&lt;/strong&gt; have request bodies while POST requests do.&lt;/li&gt;
&lt;li&gt;Be careful when testing a GET endpoint using Postman. Make sure you pass the data in the 'Params' tab instead of the 'Body' tab that is used with POST requests.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;req.query&lt;/code&gt; to view the data sent with the GET request, if you're not using route parameters or named segments. If you are using route parameters, use &lt;code&gt;req.params&lt;/code&gt; to view your data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading! Let me know how I can make this article better. Until next time 👋&lt;br&gt;
&lt;em&gt;Cover photo by Samson on Unsplash&lt;/em&gt;. &lt;em&gt;Other photos from &lt;a href="http://undraw.co"&gt;Undraw&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/10298899/how-to-send-data-in-request-body-with-a-get-when-using-jquery-ajax"&gt;https://stackoverflow.com/questions/10298899/how-to-send-data-in-request-body-with-a-get-when-using-jquery-ajax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/learn/apis-and-microservices/basic-node-and-express/"&gt;https://www.freecodecamp.org/learn/apis-and-microservices/basic-node-and-express/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>todayilearned</category>
      <category>express</category>
      <category>postman</category>
    </item>
  </channel>
</rss>
