<?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: LachPawel</title>
    <description>The latest articles on DEV Community by LachPawel (@pawel).</description>
    <link>https://dev.to/pawel</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%2F587702%2Fdc3f82cb-34b0-49ee-b915-17f57a8dcfbb.jpeg</url>
      <title>DEV Community: LachPawel</title>
      <link>https://dev.to/pawel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pawel"/>
    <language>en</language>
    <item>
      <title>That's what I was missing. Must-read for developers that want to build a solid software!</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Mon, 17 Nov 2025 19:51:53 +0000</pubDate>
      <link>https://dev.to/pawel/-4e0b</link>
      <guid>https://dev.to/pawel/-4e0b</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/dan1618/clean-architecture-with-nextjs-43cg" class="crayons-story__hidden-navigation-link"&gt;Clean architecture with Next.js&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/dan1618" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1887353%2F42dbc22f-c002-49c9-b796-8933fe0df800.png" alt="dan1618 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/dan1618" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Daniel Malek
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Daniel Malek
                
              
              &lt;div id="story-author-preview-content-1948919" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/dan1618" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1887353%2F42dbc22f-c002-49c9-b796-8933fe0df800.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Daniel Malek&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/dan1618/clean-architecture-with-nextjs-43cg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 5 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/dan1618/clean-architecture-with-nextjs-43cg" id="article-link-1948919"&gt;
          Clean architecture with Next.js
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/nextjs"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;nextjs&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cleancode"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cleancode&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/dan1618/clean-architecture-with-nextjs-43cg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;32&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/dan1618/clean-architecture-with-nextjs-43cg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>nextjs</category>
      <category>cleancode</category>
      <category>architecture</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Fine-tune a ML Model under 50 lines of code with FastAI</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Mon, 15 Jan 2024 21:09:40 +0000</pubDate>
      <link>https://dev.to/pawel/fine-tune-a-ml-model-under-50-lines-of-code-with-fastai-3op0</link>
      <guid>https://dev.to/pawel/fine-tune-a-ml-model-under-50-lines-of-code-with-fastai-3op0</guid>
      <description>&lt;h1&gt;
  
  
  Fine-tune a ML Model under 5 minutes with FastAI
&lt;/h1&gt;

&lt;p&gt;Our learning journey of Machine Learning, starts with building a very simple model for recognizing objects in the images. Worth mentioning is the fact&lt;br&gt;
that we are not going to create a model from scratch, not train it from scratch. We are going to use a pre-trained model, and fine-tune it to our needs.&lt;br&gt;
Another important to mention fact is that we will be using fastai library, which is a high-level wrapper around PyTorch. It abstracts away a lot of the&lt;br&gt;
complexities that we would have to deal with if we were to use PyTorch directly, or build our own model from scratch. In fact, as far as I know,&lt;br&gt;
it was fastai's mission to make Deep Learning more accessible to everyone, and I think they are doing a great job at it. So, let's get started.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Problem definition and FastAI Course
&lt;/h3&gt;

&lt;p&gt;Before we dive into the code, let's define the problem we are trying to solve. Let's say that we have a bunch of images of cats and dogs, and we want&lt;br&gt;
to build a model that can recognize whether the image contains a cat or a dog. This is a very simple problem, but it will allow us to get familiar with&lt;br&gt;
the fastai library, and the process of fine-tuning a model. What's more, if you would like to dig deeper and understand more, I strongly recommend&lt;br&gt;
to checkout original fastai course, which is available for free on &lt;a href="https://course.fast.ai/" rel="noopener noreferrer"&gt;fast.ai&lt;/a&gt;, as well as read the book available here: &lt;a href="https://www.amazon.com/Deep-Learning-Coders-fastai-PyTorch/dp/1492045527" rel="noopener noreferrer"&gt;Deep Learning for&lt;br&gt;
Coders with fastai and PyTorch&lt;/a&gt; and here as an online version: &lt;a href="https://github.com/fastai/fastbook" rel="noopener noreferrer"&gt;https://github.com/fastai/fastbook&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up the environment
&lt;/h3&gt;

&lt;p&gt;Unlike the course suggests, I would rather show you how to create and fine-tune the model entirely on your own machine, locally in the IDE, without any&lt;br&gt;
cloud services, nor Python notebooks. For the reference I was using Python 3.11.6 version and two main libraries used in the project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;duckduckgo_search ver: 4.2&lt;/li&gt;
&lt;li&gt;fastai ver: 2.7.13&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As well as I was using VSCode as my IDE, and macOS Ventura as my operating system. However, I will not go into details on how to install Python, nor VSCode. Python 3 installed on your machine as well as some kind of IDE should be enough to follow along.&lt;/p&gt;

&lt;p&gt;First of all you will need to create a new folder for your project, and then create a new virtual environment for it. To create a new virtual environment with venv, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new directory called env which will contain the virtual environment for your new project. After creating the virtual environment, you can activate it using the following command:&lt;/p&gt;

&lt;p&gt;On macOS or Linux:&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="nb"&gt;source env&lt;/span&gt;/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows:&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="se"&gt;\e&lt;/span&gt;nv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you activate the virtual environment, you can create a new file which will be the entry file for our project. I called mine &lt;code&gt;main.py&lt;/code&gt;. In this file we will import all the libraries we need, and write the code for our project.&lt;/p&gt;

&lt;p&gt;Last but not least we will need to install two main libraries which are fastai as PyTorch wrapper, and duckduckgo_search which will allow us to download images from the internet. To install them you can run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;fastai duckduckgo_search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Coding Time
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;main.py&lt;/code&gt; file and import the libraries we will need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;duckduckgo_search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DDGS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastdownload&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;download_url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastcore.all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sleep&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastai.vision.all&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data is the core element for building our project, in this case it will be images of cats and dogs. We will need to download them from the internet, and then split them into training and validation sets. Otherwise, we could&lt;br&gt;
of course download them manually, and then split them manually, but that would be a lot of work.&lt;/p&gt;

&lt;p&gt;To download the images we will use duckduckgo_search library. It allows us to search for images on duckduckgo.com, and then download them. Let's create a search function which will take a query and a number of images we want to download as parameters, and then return a list of downloaded images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_images&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ddgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DDGS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Searching for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ddgs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;max_images&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;itemgot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that, it may look different in the fastai course, because the library has changed since then. The same applies to the future, as the code we have just written may be obsolete one day, that's why I recommend to always check the documentation of the library you are using.&lt;/p&gt;

&lt;p&gt;Let's also verify that the function works as expected, by calling it with a query and a number of images we want to download:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dog_photo_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dog photo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_images&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog_photo_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above, will use the search_images function to search for 'dog photo' on duckduckgo.com, and then return the list of image urls. After search it will be print the url.&lt;/p&gt;

&lt;p&gt;You can test the code by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you can see the url of the image, it means that the function works as expected. Now, let's download the image using the download_url function from fastdownload library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;download_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog_photo_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dog.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show_progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above will download the image from the url, and save it as dog.jpg file. If you run the code again you should see a "dog.jpg" file in your project directory.&lt;/p&gt;

&lt;p&gt;Next, we can do the same for cat, search for one image of a cat, download it, and save in the project's directory so that we can use it later for testing our model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;download_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;search_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat photo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_images&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show_progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running &lt;code&gt;main.py&lt;/code&gt; again, you should see a "cat.jpg" file in your project directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data for Fine-Tuning Needed
&lt;/h3&gt;

&lt;p&gt;Now that we have our dog and cat photo to verify our model workings in the future, we can start gathering data for model fine-tuning. We will need to download a bunch of images of cats and dogs, and then split them into separate folders names accordingly. Let's create a function that will do that for us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;searches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dog&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dog_or_cat&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;searches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;download_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;search_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; photo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&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="c1"&gt;# Pause between searches to avoid over-loading server
&lt;/span&gt;    &lt;span class="nf"&gt;download_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;search_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; photo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&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="nf"&gt;resize_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_image_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; images removed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above will create a new directory called "dog_or_cat" in our project directory, and then download images of dogs and cats into it. It will also resize the images to 400 pixels, and remove any images that are corrupted. The code may take a while to run, depending on your internet connection, and the number of images you want to download. You can change the number of images by changing the max_images parameter in the search_images function. However, please note that it's good to have at least 30 images of each class, so that the model can learn properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fine-tuning Time
&lt;/h3&gt;

&lt;p&gt;Now that we have our data ready, we can start fine-tuning our model. First of all we will need to create a DataBlock, which will be used to create a DataLoaders object. DataLoaders object will be used to create a Learner object, which will be used to train our model. Let's start with the DataBlock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ImageBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CategoryBlock&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="n"&gt;get_items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;get_image_files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;splitter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;RandomSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valid_pct&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;get_y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;parent_label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;item_tfms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;squish&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;dataloaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above, basically creates a payload object, which will be used to fine-tune our model. Let's break it down a little bit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;DataBlock: This is a class provided by the fastai library for defining how to load and process data for a machine learning model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;blocks=(ImageBlock, CategoryBlock): This specifies the type of data the DataBlock will work with. In this case, it's working with image data (ImageBlock) and category labels (CategoryBlock).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_items=get_image_files: This specifies the function to use for getting the items (in this case, image files) that the DataBlock will work with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;splitter=RandomSplitter(valid_pct=0.2, seed=42): This specifies how to split the data into training and validation sets. It uses a random splitter with 20% of the data set aside for validation and a seed value of 42 for reproducibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;get_y=parent_label: This specifies how to get the labels for the data. In this case, it's using the parent directory of the image file as the label.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;item_tfms=[Resize(192, method='squish')]: This specifies any item transformations to apply to the data. In this case, it resizes the images to a height of 192 pixels using the "squish" method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;.dataloaders(path, bs=32): This creates the dataloaders for the data block, where path is the directory containing the image files, and bs=32 specifies the batch size for the dataloaders.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that we have our DataBlock ready, we can create a Learner object, which will be used to train our model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;learn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;vision_learner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resnet18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;error_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above, creates a Learner object, which will be used to train our model. What we do here is pass the &lt;code&gt;dls&lt;/code&gt; object which is a payload of data for our model, and the &lt;code&gt;resnet18&lt;/code&gt; model which is a pre-trained model provided by fastai library. We also specify the &lt;code&gt;error_rate&lt;/code&gt; metric, which will be used to evaluate our model.&lt;/p&gt;

&lt;p&gt;Last but not least, we will need to fine-tune our model. To do that we will use the &lt;code&gt;fine_tune&lt;/code&gt; method provided by the Learner object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;learn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fine_tune&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above, fine-tunes our model for 10 epochs. You can change the number of epochs by changing the number in the fine_tune method. However, please note that it's good to fine some sweet spot, where the model is not overfitting, but also not underfitting. You can read more about it in the fastai course. So too much data, or too much epochs is not necessarily a good thing, and the same applies to too little data, or too little epochs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Evaluation
&lt;/h3&gt;

&lt;p&gt;Our model is fine tuned, we gathered the data, and now it's time to evaluate it. Let's give it our dog and cat photo from the beginning, and see what it predicts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;predicted_animal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;prediction_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;prediction_probability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;learn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PILImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dog.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The photo depicts: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;predicted_animal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Probability: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prediction_probability&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;prediction_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;predicted_animal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;prediction_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;prediction_probability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;learn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PILImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cat.jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The photo depicts: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;predicted_animal&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Probability: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prediction_probability&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;prediction_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we do here is we use the predict method provided by the Learner object, and pass it the image we want to predict. Then we print the result, which is a tuple containing the predicted class, the predicted tensor's index, and the array of predictions probability. The prediction probability is a number between 0 and 1. Feel free to play around with this code, brake it, rebuild, or even try to predict your own images.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article we have learned how to fine-tune a pre-trained model using fastai library. We have also learned how to gather data for our model, and how to evaluate it. I hope you have enjoyed reading this article, and that you have learned something new. If you have any questions or comments, please feel free to leave them below. I will be happy to answer them. It also marks the end of the first part&lt;br&gt;
of fastai course series. Again I strongly recommend to check out the original fastai course, as well as the book. In the next part we will learn how to deploy our model to the web, and make it available for everyone to use. So stay tuned, and see you in the next article.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>fastai</category>
      <category>learning</category>
    </item>
    <item>
      <title>Something Ends, Something Begins - Learning ML with Deep Learning for Coders Intro</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Sun, 14 Jan 2024 22:08:38 +0000</pubDate>
      <link>https://dev.to/pawel/something-ends-something-begins-learning-ml-with-deep-learning-for-coders-intro-mh7</link>
      <guid>https://dev.to/pawel/something-ends-something-begins-learning-ml-with-deep-learning-for-coders-intro-mh7</guid>
      <description>&lt;h3&gt;
  
  
  Embracing Change: Reflecting on the Past and Looking Forward to the Future
&lt;/h3&gt;

&lt;p&gt;Some things come to an end, while other begin - that's what was on my mind when I started writing this blog post. It's also the beginning of a new year, which marks some changes in my life and also the changes in the whole IT industry. What's more, I would like to dedicate this post to my grandmother - who I lost on the day of writing this post. She is a huge inspiration for me as she was World War II survivor, experienced a lot of tragedies in her life, witnessed a lot of changes in the world, but she managed to keep up with her life and constant changes quite well. Born before World War II, in times when still so many people used to ride horses, when cars and TVs were known but they were rather a luxury, and something that only certain people could afford. Now, we have smartphones, smartwatches, smart TVs, and even smart fridges. We have the Internet, social media, and so many things that we couldn't even imagine 50 years ago.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Rapidly Changing Landscape of the IT Industry
&lt;/h3&gt;

&lt;p&gt;A couple of years ago when I was starting my web-development learning journey, I recall that JavaScript was still very popular, as well as class components in React. Fast-forward to 2024, and I have a feeling that most of the IT industry switched to TypeScript (even though we have some dramas from time to time), as well as I haven't seen much class components in React anymore. Those are just a few examples of how fast the IT industry is changing, and how important it is to keep up with the changes. However, it's also important not to get too much over-hyped about the new technologies, and to be able to distinguish between the hype and the real value. In the recent years we had a several examples of over-hyped technologies, that in the end didn't bring much value, and were just a waste of time. What's more is that especially people with less experience in the industry, tend to get over-hyped about the new technologies, and they tend to jump on the hype train without even thinking about the real value of the technology. It happens especially when we don't have a strong understanding of the programming fundamentals, and a strong understanding of the technology that we are using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflection on Technology Trends: Prioritising Impact Over Hype
&lt;/h3&gt;

&lt;p&gt;Some of you readers may recall my previous articles or YouTube videos, where I enthusiastically embraced various tech trends like blockchain, smart contracts, and cutting-edge frontend frameworks. Despite the valuable lessons learned, numerous hackathon victories, and even co-founding a startup, I can't help but feel that many of these ventures lacked the necessity of reinventing the wheel and failed to deliver significant value. Ironically, one of my earliest creations, the Student Portfolio Grade Calculator, left a more substantial impact and demonstrated a more practical use case than the dozens of sophisticated apps I developed later on. Consequently, after these experiences, I made a conscious decision to step back, maintain a healthy distance from the allure of new technologies, and take an extended break from content creation. Instead, my focus shifted towards reinforcing the fundamentals and closely observing the industry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unveiling the Practicality of AI and Long-Lasting Innovations
&lt;/h3&gt;

&lt;p&gt;Over the last couple of years, and even decades, numerous technologies have emerged with promises to revolutionise our world. However, many of them fell short of practicality and failed to address real-world problems. On the flip side, technologies like the Internet, smartphones, and social media platforms have undeniably reshaped our lives, offering efficient tools that prove challenging to replace. Where does AI fit into this narrative? I'll leave that judgment to you, but consider that the concept of AI, particularly the underlying machine learning principles, has been around for years. It didn't materialise suddenly; rather, it has existed in various forms, solving real problems throughout its evolutionary journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking Action: Navigating the Rapidly Evolving Landscape of Artificial Intelligence
&lt;/h3&gt;

&lt;p&gt;Last but not least, what can be done about this? Should we just ignore AI, go all-in on hype about this technology, panic that it will replace us and even destroy the humanity, or maybe it's better to get to know the concept finally a bit better and prepare ourselves for a new era? I personally think that the last option is the best one, and that's why I decided to write this article. I would like to share with you my journey of learning AI and Machine Learning, and also show you how to build something practical and useful with this technology. Let's get started!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>programming</category>
    </item>
    <item>
      <title>What the WEB3? Understand WEB3 by Creating a Token Inside of a Node.js App</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Sun, 16 Jan 2022 20:36:45 +0000</pubDate>
      <link>https://dev.to/pawel/what-the-web3-understand-web3-by-creating-a-token-inside-of-a-nodejs-app-2kj2</link>
      <guid>https://dev.to/pawel/what-the-web3-understand-web3-by-creating-a-token-inside-of-a-nodejs-app-2kj2</guid>
      <description>&lt;h2&gt;
  
  
  What is WEB3?
&lt;/h2&gt;



&lt;p&gt;Before we dive into the code and start building our own crypto token, let's answer briefly the question what is the whole idea behind the WEB3, Cryptocurrencies, Decentralization, NFTs etc. Currently we are in so-called era of Web 2.0, what simply means that unlike WEB 1.0, where we could mainly read chunks of information from the web, now we can also interact with each other, and add our own blocks to this puzzle in form of posts, pictures, videos, or even likes. The problem here is that firstly we have to use some kind of 3rd party provider, and as a result the hosting service between us, holds our data. This leads to various issues, such as privacy concerns, ownership concerns, incompatibility with other services, and so on. WEB3 on the other hand, tries to solve these issues, at least in some way. If you remember P2P networks such as Torrents, that used to be very infamous years ago, than you may already have a clue of what WEB3 is. Indeed, it's not a super revolutionary technology, rather it's like just going back to the roots of the Internet, and peer to peer connections where chunks of data are copied and spread among users of the given network. Additionally, blockchain is used at the top of it, to add another layer of security and &lt;strong&gt;Immutability&lt;/strong&gt;. Blockchain in a most simplified form, is a kind of a Virtual Machine that runs on all of the supporter nodes (blockchain nodes), also very often called &lt;strong&gt;miners&lt;/strong&gt; who store and process the whole data in the exact same way. In other words, it can be said that blockchain is a machine of state, and that machine's state is maintained by all of the nodes in the given network. There are many networks like that, and they can be supported just by a few computers, up to thousands of them - Bitcoin for example.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Decentralization&lt;/strong&gt; is another keyword here, as we have to store the same data on all of the computers that support the given network (miners), instead of having one source of truth like it takes places in case of centralized solutions (web 2.0). It's not a perfect solution, as it may lead to a huge energy consumption, it's very expensive and slow because every action that modifies the state, has to be approved by the whole network, and updated on every single computer supporting the network. Additionally, we also have to hash the data, and find the solution of the next block to link it with the previous one - what is the main reason why bitcoin miners spend so much money on the most fancy graphic cards. On the other hand, we get an ultimate security layer - the more computers there are in the network, the harder it gets to manipulate the data and attack the network. Most probably it is also one of the reason why Bitcoin, and few other big cryptocurrencies are so expensive. Their value also derives from the scale of how many computers are supporting them, how many people had to spend a lot of money, and time for the equipment, electricity, and the Internet bills.&lt;/p&gt;



&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;p&gt;There is a lot of hype around WEB3 possibly replacing WEB2 in the nearest future. However, after reading the intro you may already have clue that it not necessary a good idea. Even though, there are many advantages of decentralization and blockchain, it's rather good for storing very sensitive data, than for storing huge static files, and other generic things. It would cost millions to decentralize literally everything on the Internet, plus it could slow down many processes, and make this technology almost unusable. Most of the time, the architecture of the Web3 apps is not very different from what we already know from Web2, and it's more of an extension to the current stack than the replacement. Below you can see the simplest representation of the web2 and web3 apps. Some people also tend to think that blockchain can be a replacement for the traditional backend, what is partly true and even possible to do, but in any bigger production it would be too expensive and slow. That is why, blockchain is most of the time added at the top of this technologies, to add additional layer of security.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fd2h2p9f6ar7pfc43672w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fd2h2p9f6ar7pfc43672w.jpg" alt="Web2 vs Web3" width="800" height="565"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;



&lt;p&gt;In this particular tutorial, we are going to use several technologies, but the only prerequisite is knowing basics of JavaScript, and having Node.js installed on your computer. Below you can find a list of the technologies, libraries, and services that we will be using in this tutorial, with related links and short description.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; - JavaScript Runtime&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://metamask.io/" rel="noopener noreferrer"&gt;Metmask&lt;/a&gt; - Crypto Wallet that stores our address which is our ID number or/and profile in the decentralized world&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.soliditylang.org/en/v0.8.11/" rel="noopener noreferrer"&gt;Solidity&lt;/a&gt; - a programming language used for building decentralized apps&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hardhat.org/" rel="noopener noreferrer"&gt;Hardhat&lt;/a&gt; - a JavaScript library that works as an environment for compiling, deploying, and testing decentralized applications written in Solidity&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.alchemy.com/" rel="noopener noreferrer"&gt;Alchemy&lt;/a&gt; - a service that works as a bridge between our local project and real blockchain&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Node.js (especially versions 16 and higher) is the only thing that you will need to continue, rest of the things will be explained later, but if you want you can install Metamask browser extension and create a free account on Alchemy. Additionally, you can install some extension for Solidity in your favorite editor (such as VS Code) to highlight the syntax.&lt;/p&gt;



&lt;h2&gt;
  
  
  Coding Time
&lt;/h2&gt;



&lt;p&gt;First of all, open an empty folder where you would like to create the project, and then open the terminal. From the terminal we will create a new directory, initiate a new node.js project, and install hardhat library. Just enter the following commands:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir tokenApp
cd tokenApp
npm init -y
npm install hardhat --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Once you have the project and hardhat library ready, it's time to create a new template structure for our future decentralized application. Just like in case of React, where we have "npx create-react-app nameoftheapp command", hardhat allows us to do a very similar thing. For this purpose, enter following command: &lt;code&gt;npx hardhat&lt;/code&gt;. This command will start the process of creating a new application, just hit enter for everything.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.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%2F6e36jmb7vpc0kuo22dcz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6e36jmb7vpc0kuo22dcz.png" alt="Hardhat" width="629" height="306"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;After installing all of the dependencies, your package.json file should look more or less like that:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "tokenApp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@nomiclabs/hardhat-ethers": "^2.0.4",
    "@nomiclabs/hardhat-waffle": "^2.0.1",
    "chai": "^4.3.4",
    "ethereum-waffle": "^3.4.0",
    "ethers": "^5.5.3",
    "hardhat": "^2.8.2"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;If some of the libraries are missing, feel free to install them manually. Now it's also the time to open the editor in the given directory (&lt;code&gt;code .&lt;/code&gt; command should open VS Code). When you check the content of the directory you should see 3 new folders:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;contracts&lt;/li&gt;
&lt;li&gt;scripts&lt;/li&gt;
&lt;li&gt;test&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;In the first one, we will add Solidity code which will be later compiled to the machine code by hardhat library. The second one is for JavaScript scripts, that will let us deploy or/and interact with our application on the blockchain. Test just like name reveals, is the place where we store test files to check if our code written in Solidity works fine, before deploying it to the blockchain. For now, you can just delete all of the files inside of those folders, as we will create everything from scratch. There should be also one more file called &lt;code&gt;hardhat.config.js&lt;/code&gt; in the main directory, and it's the file which will work as a configuration for our whole project, but will move on to it later.&lt;/p&gt;



&lt;h2&gt;
  
  
  Hello Solidity!
&lt;/h2&gt;



&lt;p&gt;Finally, it's the time when we finally start to write some code in another language - Solidity, that will eventually live on the blockchain. But hey, what is Solidity? Solidity is a programming language that looks very similar to JavaScript, but with a few major differences:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;Statically typed&lt;/li&gt;
&lt;li&gt;Object Oriented&lt;/li&gt;
&lt;li&gt;Compiled&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Even though, it's a completely different language, if you have experience with JavaScript or other similar language, you should be familiar with 80% of the syntax. Now, open &lt;code&gt;contracts&lt;/code&gt; folder and create a new file called &lt;code&gt;HelloWorldToken.sol&lt;/code&gt;. Inside of this file add the following code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract HelloWorldToken {
    string public name = "HelloToken";
    string public symbol = "HWT";
    uint public totalSupply = 1000;
    mapping(address =&amp;gt; uint) balances;

    constructor() {
        balances[msg.sender] = totalSupply;
    }

    function transfer(address to, uint amount) external {
        require(balances[msg.sender] &amp;gt;= amount, "Not enough tokens");
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    function balanceOf(address account) external view returns (uint) {
        return balances[account];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Just take a while and study the code, if you are familiar with programming in general the code shouldn't be very difficult to understand. There are a few things that may look odd though:&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;First two lines indicate the license and Solidity compiler version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;contract&lt;/strong&gt; - basically just like &lt;strong&gt;class&lt;/strong&gt; in other languages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mapping&lt;/strong&gt; - something like &lt;strong&gt;map&lt;/strong&gt; in JavaScript or dictionary in other languages, that let us store key: value pairs&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;address&lt;/em&gt; - a special type of hexadecimal string with the public address of a given person's wallet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;msg.sender&lt;/strong&gt; - a global variable that always points to the address of the person who called the given function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;constructor&lt;/strong&gt; - runs only once, when we deploy the instance of our contract to the blockchain&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Compilation Time
&lt;/h2&gt;



&lt;p&gt;Like it was mentioned before, Solidity is a compiled language and has to be compiled to the binary code, before we deploy it to the blockchain. Our application/ smart contract is currently written in Solidity, but blockchain itself cannot understand it. In order to compile our Solidity code to the binary code, run following command &lt;code&gt;npx hardhat compile&lt;/code&gt;.&lt;/p&gt;



&lt;h2&gt;
  
  
  Is ABI an API?
&lt;/h2&gt;



&lt;p&gt;When it comes to the traditional apps, we have something called API (Application Programming Interface) which is a way of interacting with a given code between two abstract environments. In the world of WEB3, this pattern is called ABI (Application Binary Interface) which is in fact some sort of a lower level of API. When we compile our contract, a new directory is created in the root of the project, and when you go to the&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./artifacts/contracts/HelloWorldToken.sol/HelloWorldToken.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;you will see that there a json file with a set of instructions and the bytecode of our application. Using this set of instructions, we will interact with the smart contract, after it's deployment to the blockchain.&lt;/p&gt;



&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;



&lt;p&gt;Do you remember that blockchain is &lt;strong&gt;immutable&lt;/strong&gt; ? Well, this is one of the reasons why we have to be very careful and test our contract before deploying it to the blockchain. Moreover, as you know our contracts may be related with a huge money, so the smallest mistake in the code may cost millions. Fortunately, we can test our contract for free, and even we don't have to deploy it to the blockchain. Instead, we create a local blockchain on our computer, that will simulate the real one, to execute and test our contract's functions. Hardhat has all of the tools built-in, therfore there is no need to worry about the rest. Go to the &lt;code&gt;test&lt;/code&gt; folder and create a new file called &lt;strong&gt;HelloWorldToken.test.js&lt;/strong&gt;. Inside of this file you can add the following code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("HelloWorldToken", function () {
  let token;

  const tokenReceiver = "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f";

  beforeEach(async () =&amp;gt; {
    const HelloWorldToken = await ethers.getContractFactory("HelloWorldToken");
    token = await HelloWorldToken.deploy();
    await token.deployed();
  });

  it("Should return the name of the token", async function () {
    expect(await token.name()).to.equal("HelloToken");
  });

  it("Should return the symbol of the token", async function () {
    expect(await token.symbol()).to.equal("HWT");
  });

  it("Should return a total supply of the token", async function () {
    const totalSupply = await token.totalSupply();

    expect(String(totalSupply)).to.equal("1000");
  });

  it("Should transfer tokens to the other account", async function () {
    // given

    const sendTransaction = await token.transfer(tokenReceiver, 200);

    // when

    await sendTransaction.wait();

    const addressBalance = await token.balanceOf(tokenReceiver);

    // then

    expect(String(addressBalance)).to.equal("200");
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;After that, go back to the terminal and run the test by executing the following command &lt;code&gt;npx hardhat test&lt;/code&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Predeployment
&lt;/h2&gt;



&lt;p&gt;Our Solidity code is ready and compiled, tests are passing, but still it's available only on our local machine, so what is the purpose of it? It's like having website only on our hard drive. To let others interact with it, we have to deploy it to the real blockchain, and to do that we will need a crypto wallet and some blockchain node. First one is necessary, to pay for the deployment as deployment process is a "write" operation, and it does introduce changes to the blockchain which have to be approved by all of the supporters what generates costs. We also need a blockchain node, to connect with a given network and upload our code from our computer to the blockchain network. In fact there are many wallets, and node providers, but for the sake of simplicity we will stick to Metamask, Alchemy, and Ethereum Rinkeby Test Network. First of all we have to create a Metamask wallet, the process is super simple but if you have some problems you can just follow the guide that can be found &lt;a href="https://metamask.zendesk.com/hc/en-us/articles/360015489531-Getting-started-with-MetaMask" rel="noopener noreferrer"&gt;here&lt;/a&gt;. After setting up the Metamask account, there is one more important detail - we are not going to deploy our application to the Ethereum Mainnet, because every operation there costs real Ethereum and real money. Instead we are going to use Ethereum Rinkeby testnet, which is just like name says, a test version of Ethereum network. Unfortunately, we also have to pay for the transactions there, but we can get some free test Ethereum from a faucet. Before we get some free test Ethereum, we should switch to the test network in our Metamask - to do that just click on the Metamask extension, click networks and select Rinkeby. If you cannot see any test networks, you may need to turn them on in settings. Nevertheless, you should see something like on the picture below.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fuuuk9jj5kybx28geab64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuuuk9jj5kybx28geab64.png" alt="Metamask Rinkeby" width="277" height="465"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;When your Metamask account is ready, it's time to get some free test Ethereum. You can get some from &lt;a href="https://faucets.chain.link/rinkeby" rel="noopener noreferrer"&gt;here&lt;/a&gt; Just copy-paste your public address from the metamask, enter the address, and submit. You should get 0.1 eth on your account within a couple of minutes. It will be more than enough to deploy our application. There is one more point missing and it's a blockchain node. Actually, we could run our own node, but it would be very complicated and time consuming, that is why we can use services such as &lt;a href="https://alchemy.com/?r=552689cf93f064ec" rel="noopener noreferrer"&gt;Alchemy&lt;/a&gt;. Just go to &lt;a href="https://alchemy.com/?r=552689cf93f064ec" rel="noopener noreferrer"&gt;Alchemy&lt;/a&gt; and create a new account. The process is quite straightforward so I won't explain it here, after registration create a new app, and be sure to select &lt;strong&gt;Ethereum&lt;/strong&gt; Chain, &lt;strong&gt;Staging&lt;/strong&gt; environment and &lt;strong&gt;Rinkeby&lt;/strong&gt; network. It should look more or less like on the picture below.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.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%2Fba5s6vsanq68b8g4lieb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fba5s6vsanq68b8g4lieb.png" alt="Alchemy" width="800" height="88"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Great! Now we have our wallet ready, with some test Eth on it, plus we also have a portal to a blockchain. It's finally time for the last corrections and deployment. Before we deploy our app, we need to configure the local environment and create a script for the deployment. Go back to your project, open &lt;code&gt;hardhat.config.js&lt;/code&gt; file, and add the following code to it:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require("@nomiclabs/hardhat-ethers");
require("dotenv").config();

const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
  solidity: "0.8.0",
  networks: {
    rinkeby: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`],
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;As you may see we are using some sensitive information here, and we need dotenv library to support .env files. Open terminal and input following command &lt;code&gt;npm install dotenv&lt;/code&gt;. After it's downloaded, create ".env" file in the root directory of the project and add a following keys:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   API_URL=&amp;lt;ALCHEMY_API_URL&amp;gt;
   API_KEY=&amp;lt;THE_LAST_PART OF_THE_API_URL&amp;gt;
   PRIVATE_KEY=&amp;lt;YOUR_WALLET'S_PRIVATE_KEY&amp;gt;
   CONTRACT_ADDRESS=&amp;lt;DEPOLOYED_TOKEN_ADDRESS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;For now, you can skip the CONTRACT_ADDRESS key. API_URL and API_KEY can be found on the Alchemy website under "VIEW KEY" button, as a "HTTP" key. Your private key to your address can be extracted from the Metamask like &lt;a href="https://metamask.zendesk.com/hc/en-us/articles/360015289632" rel="noopener noreferrer"&gt;that&lt;/a&gt; However, &lt;strong&gt;NEVER EVER SHARE YOUR PRIVATE KEY WITH ANYONE&lt;/strong&gt;. That is why, I also suggest not to use this account for real transactions.&lt;/p&gt;



&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;



&lt;p&gt;Now, it's final time to deploy our smart contract to the blockchain, there is only one more file to add and we are ready to deploy. Open scripts folder and create a file called &lt;code&gt;deploy.js&lt;/code&gt;, inside of it add the following code.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(async () =&amp;gt; {
  try {
    const HelloWorldToken = await ethers.getContractFactory("HelloWorldToken");

    const deployedToken = await HelloWorldToken.deploy();

    console.log("Contract deployed to address:", deployedToken.address);

    process.exit(0);
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
})();

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

&lt;/div&gt;





&lt;p&gt;The last point is executing the following command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run scripts/deploy.js --network rinkeby
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;After that you should see something like that:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract deployed to address: 0xc8B329B720bD37aAb9A4B2D9Fe61AF3d4EF8C4eb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Congratulations! Your contract has been successfully deployed to the blockchain! :)&lt;/p&gt;



&lt;h2&gt;
  
  
  Interaction
&lt;/h2&gt;



&lt;p&gt;Now our contract is ready, tested, and deployed, but how can we interact with it? Copy the address of the contract to the .env file, open scripts folder, create a new file, call it "interact.js", and add the following code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const API_KEY = process.env.API_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;

const contract = require("../artifacts/contracts/HelloWorldToken.sol/HelloWorldToken.json");

const alchemyProvider = new ethers.providers.AlchemyProvider(
  (network = "rinkeby"),
  API_KEY
);

const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider);

const helloWorldTokenContract = new ethers.Contract(
  CONTRACT_ADDRESS,
  contract.abi,
  signer
);

(async () =&amp;gt; {
  process.stdout.write("Fetching the data. Please wait");
  const dotsIncrement = setInterval(() =&amp;gt; {
    process.stdout.write(".");
  }, 1000);

  const tokenName = await helloWorldTokenContract.name();
  const tokenSymbol = await helloWorldTokenContract.symbol();
  const tokenSupply = await helloWorldTokenContract.totalSupply();

  clearInterval(dotsIncrement);
  process.stdout.write("\n");

  console.log(
    `
       Name: ${tokenName}
       Symbol: ${tokenSymbol}
       Supply: ${String(tokenSupply)}`
  );
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;This is the simplest way of interacting with our token contract, to run the code above, open terminal and input the command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx hardhat run scripts/interact.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;If everything goes OK, you should see the basic information about your token, right from the blockchain. Moreover, you can also add your token to the Metamask wallet. To do that just click on the &lt;code&gt;import token&lt;/code&gt; button, then paste the address of your token contract, and set 0 as a decimal places. When you click import, you should see 1000 Tokens. When you go to &lt;strong&gt;"&lt;a href="https://rinkeby.etherscan.io/token/" rel="noopener noreferrer"&gt;https://rinkeby.etherscan.io/token/&lt;/a&gt;"&lt;/strong&gt; and add the address of your contract to the end of the link, you should also see some extra info about your token. Currently it will be just you, since you were the person who deployed the contract, and as you may remember in the &lt;code&gt;constructor&lt;/code&gt; we assign the total supply of the token, to our own account.&lt;/p&gt;



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



&lt;p&gt;Repository with the related code can be found &lt;a href="https://github.com/KowalewskiPawel/Solidity-Token-Templates" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Congratulations once again! Now you can send your token to the others, but nothing more than that. Our Token is a custom token, that doesn't meet any standards, which of course exist in the crypto world. Even if you wanted to deploy it to the mainnet, it would be probably a waste of money. Also this was just a demonstration, you can treat it as a boilerplate to create your own tokens or NFTs, but you should definitely build them according to the standards such as ERC-20 or ERC-721. Moreover, I have used Hardhat, Metamask, and Ethereum Rinkeby testnet, but there are many other technologies out there, which would work as well. Once you get the concept of creating smart contracts, switching to a new technology shouldn't be an obstacle for you. There is also one more missing part - frontend app to make the communcation with our app/token easier. You can either try to create one now, or check my other tutorials where this kind of article may show up. :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>web3</category>
      <category>node</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Unit Testing Node.js REST API (MongoDB) with Mocha</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Fri, 16 Jul 2021 17:56:56 +0000</pubDate>
      <link>https://dev.to/pawel/unit-testing-node-js-rest-api-mongodb-with-mocha-1f35</link>
      <guid>https://dev.to/pawel/unit-testing-node-js-rest-api-mongodb-with-mocha-1f35</guid>
      <description>&lt;p&gt;Unit Testing Node.js REST API with MongoDB&lt;/p&gt;

&lt;p&gt;Many of us are focused on writing the code to that extent, we very often tend to forget about testing it. Some of you may say just run the app at check it manually. Well, it may work for some smaller apps, but what if we forget about some edge case or our app simply grow bigger? Not to mention, working on a bigger project in a team. That is why there are even separate teams responsible only for writing tests. Even if you are just a learner or a potential junior dev candidate, it is better to grasp some testing knowledge and start testing your apps. Indeed, there are many more things to be said about testing, as it is a broad topic.&lt;/p&gt;

&lt;p&gt;This time, we will stick only with the absolute basics about testing REST API routes. In my previous tutorials, we were building a simple REST API with Node.js and MongoDB. Hence, this time we will continue developing the same project by adding new features, so you can either get the boilerplate code from the previous tutorials or stick along with me and try to implement the code inside of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocha - The Framework
&lt;/h2&gt;

&lt;p&gt;To make our testing working easier, we will need a few tools. &lt;a href="https://mochajs.org/" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt; is a JavaScript framework for testing purposes. All of our tests will base on the top of Mocha, but it's not the only tool. Treat it as a skeleton for our "testing" body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chai
&lt;/h2&gt;

&lt;p&gt;Once we have our testing framework, we will also need some library that will help us "compare" values and give results accordingly. &lt;a href="https://www.chaijs.com/" rel="noopener noreferrer"&gt;Chai&lt;/a&gt; is a library that can be used with many tools, but in this project, we will use only the &lt;code&gt;expect&lt;/code&gt; function that will help us compare the expected values to the actual ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supertest
&lt;/h2&gt;

&lt;p&gt;REST API, like the name itself explains, is based on the API calls. That is why we will need some extra tools that will help us run the whole app with the API calls and database connection. Thanks to &lt;a href="https://www.npmjs.com/package/supertest" rel="noopener noreferrer"&gt;Supertest&lt;/a&gt; library, it becomes quite easy. It allows us to import our app module to the testing files, run the app temporarily for testing purposes and send API calls.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coding Time
&lt;/h1&gt;

&lt;p&gt;First of all, we will need to install all of the dependencies. Open the project folder, go to the terminal and type in &lt;code&gt;npm i mocha chai supertest&lt;/code&gt;. It will install all of the necessary dependencies, and we are ready to go.&lt;/p&gt;

&lt;p&gt;The next step will be configuring the &lt;code&gt;package.json&lt;/code&gt; file, by adding a new script for testing. Open the package.json file and add the following line inside of the scripts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"test": "NODE_ENV=testing mocha --recursive --exit --timeout 10000"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NODE_ENV=testing&lt;/code&gt; means that we set the global environment variable called "NODE_ENV" inside of the &lt;code&gt;.env&lt;/code&gt; file to "testing", so we will have to create it. For the time being you can open the &lt;code&gt;.env&lt;/code&gt; file and add the following line &lt;code&gt;NODE_ENV="development"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we have "mocha" which as you may guess, will run the mocha, and after that, we have several flags. &lt;code&gt;--recurisive&lt;/code&gt; means that mocha will look inside of the subdirectories for testing files, &lt;code&gt;--exit&lt;/code&gt; will force mocha to stop working once it's done with testing, and &lt;code&gt;--timeout 10000&lt;/code&gt; will give us more time for the processing time. As our app connects to the database, reads and creates data, it may take some time to finish. If we didn't set this timeout, it would simply crash.&lt;/p&gt;

&lt;p&gt;Another point related to the configuration is creating a new collection inside of the database because we will add the same data over and over again.&lt;/p&gt;

&lt;p&gt;1 Open MongoDB dashboard&lt;br&gt;
2 Go to the given project&lt;br&gt;
3 Create a new collection&lt;br&gt;
4 Add a new variable in the &lt;code&gt;.env&lt;/code&gt; file called "MONGO_URI_TEST". Now you can basically copy-paste the previous link of the original database, but change the name of the collection in the string, to the test one.&lt;/p&gt;

&lt;p&gt;All right! Our test database is created and almost everything is ready to start writing tests. But we will need to change some settings inside of the "app.js" file before we move on. &lt;/p&gt;

&lt;p&gt;Open "app.js" file and add a new variable called "database" right after "port" variable &lt;code&gt;let database = process.env.MONGO_URI;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now in the part which connects with the database, change the first argument to that variable so it looks more or less like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongoose
  .connect(database, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useFindAndModify: false,
  })
  .then(() =&amp;gt; {
    console.log("Database connection established");
  })
  .catch((err) =&amp;gt; {
    console.error(`ERROR: ${err}`);
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now right above it, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (process.env.NODE_ENV === "testing") {
  database = process.env.MONGO_URI_TEST;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will set our database variable to the test database one, based on whether we are in testing mode or not.&lt;/p&gt;

&lt;p&gt;At the bottom of the &lt;strong&gt;app.js&lt;/strong&gt; file add the export expression so that we can import it into the testing files.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export default app;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Time
&lt;/h2&gt;

&lt;p&gt;Finally, we can move on to writing tests. In the root directory create a new folder called "test" and inside of it another one called "api",  then create a file called &lt;strong&gt;users.test.js&lt;/strong&gt;. Since there is only one route called "users" in our app, we will test only that route. But the more routes your app has, the more tests you can add.&lt;/p&gt;

&lt;p&gt;Inside of the &lt;strong&gt;users.test.js&lt;/strong&gt; file, we will have to import a few libraries and modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import request from "supertest";
import { expect } from "chai";
import dotenv from "dotenv";
dotenv.config();

import app from "../../app.js";

import User from "../../models/user.model.js";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we will add new users to the database, lets create some variables that will stay in the global scope of the testing file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const tempUser = {
  username: process.env.USER_TEST,
  password: process.env.USER_TEST_PASSWORD,
};

let tempToken;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there are two more values that can be added to the ".env"  and those are example username and password.&lt;/p&gt;

&lt;p&gt;Just to be on the safe side, and give our app some extra time to establish the database connection let's add a timeout function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;before(function (done) {
  this.timeout(3000);
  setTimeout(done, 2000);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we can add tests functions. Let's start with signing up new users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("POST users", () =&amp;gt; {
  it("should register new user with valid credentials", (done) =&amp;gt; {
    request(app)
      .post("/users/signup")
      .send(tempUser)
      .expect(201)
      .then((res) =&amp;gt; {
        expect(res.body.username).to.be.eql(process.env.USER_TEST);
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });

  it("shouldn't accept the username that already exists in the database", (done) =&amp;gt; {
    request(app)
      .post("/users/signup")
      .send(tempUser)
      .expect(400)
      .then((res) =&amp;gt; {
        expect(res.body.message).to.be.eql("Username is already in use");
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of the methods on a given route will be divided into separate &lt;code&gt;describe&lt;/code&gt; functions with the first parameter as a description string, and the second one as callbacks for executing the tests. Every single test will be inside of the &lt;code&gt;it&lt;/code&gt; function which has a similar syntax to descript, with the exception of &lt;code&gt;done&lt;/code&gt; parameter which will be called each time we move on to the next test. Indeed &lt;code&gt;done&lt;/code&gt; parameter adds some kind of asynchronous logic to our tests. Then we call &lt;code&gt;request&lt;/code&gt; function from "supertest" library, which will then execute API calls with a parameter such as adding the method, body, setting headers, and getting the response. We do the testing inside of the &lt;code&gt;then&lt;/code&gt; part, and at the end, we always have to add &lt;code&gt;done()&lt;/code&gt; as otherwise, our tests will get stuck at that point. &lt;/p&gt;

&lt;p&gt;Now you can run the test with the following command &lt;code&gt;npm run test&lt;/code&gt;. It will automatically run mocha, which will execute all of the tests and show the results in the console. By the convention, it is always better to write tests and test each of them right after writing. If it fails, try to fix the problem and do not move on with writing new tests until you get the first one passing.&lt;/p&gt;

&lt;p&gt;When tests are passing it's time to add new ones. Let's test the "PATCH" methods now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("PATCH users", () =&amp;gt; {
  it("should accept correct credentials", (done) =&amp;gt; {
    request(app)
      .patch("/users/login")
      .send(tempUser)
      .expect(200)
      .then((res) =&amp;gt; {
        expect(res.body.message).to.be.eql("User logged in successfully");
        tempToken = `Bearer ${res.body.accessToken}`;
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });

  it("shouldn't accept invalid password", (done) =&amp;gt; {
    tempUser.password = process.env.USER_TEST_PASSWORD + "asdf";
    request(app)
      .patch("/users/login")
      .send(tempUser)
      .expect(400)
      .then((res) =&amp;gt; {
        expect(res.body.message).to.be.eql("Invalid password");
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });

  it("shouldn't accept non-exisiting username", (done) =&amp;gt; {
    tempUser.username = process.env.USER_TEST + "asdf";
    request(app)
      .patch("/users/login")
      .send(tempUser)
      .expect(404)
      .then((res) =&amp;gt; {
        expect(res.body.message).to.be.eql("Account not found");
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });

  it("should log out users with valid token", (done) =&amp;gt; {
    request(app)
      .patch("/users/logout")
      .set({
        Authorization: tempToken,
      })
      .expect(200)
      .then((res) =&amp;gt; {
        expect(res.body.message).to.be.eql("User logged out");
        done();
      })
      .catch((err) =&amp;gt; done(err));
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is very similar to the previous one, with the extra detail of storing the user's token and using it for logging out purposes. &lt;/p&gt;

&lt;p&gt;After finishing the tests, we should get rid of the temporary user that we have created in our test database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;after(async () =&amp;gt; {
  try {
    await User.deleteOne({ username: process.env.USER_TEST });
  } catch (err) {
    console.error(err);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like before starting tests we had a &lt;code&gt;before&lt;/code&gt; function, now we have &lt;code&gt;after&lt;/code&gt; function which deletes the temporary from our test database, to let us execute the same tests once again.&lt;/p&gt;

&lt;p&gt;In everything went OK, you should see something like that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fn8b2hvj2ynm1itb2qmzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fn8b2hvj2ynm1itb2qmzk.png" alt="Successful Tests" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Testing is a huge topic, and we have only scratched the surface. Hopefully, it gave you some idea of how to test your API routes and how to implement also database in it. Don't forget to clean up after each test, and avoid testing on the production database. Stay tuned for more, as in the next tutorial I will teach you how to add email authentication to your application without using any external services such as Firebase or AWS.&lt;/p&gt;

</description>
      <category>node</category>
      <category>testing</category>
      <category>mocha</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>How to Secure your API's Routes with JWT Token</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Wed, 14 Jul 2021 15:05:13 +0000</pubDate>
      <link>https://dev.to/pawel/how-to-secure-your-api-s-routes-with-jwt-token-4bd1</link>
      <guid>https://dev.to/pawel/how-to-secure-your-api-s-routes-with-jwt-token-4bd1</guid>
      <description>&lt;p&gt;Imagine yourself registering for a few days long conference about JavaScript. Before you go there, you have to enter your information and get a ticket. Once you reach the conference, security checks your ticket, ID, and give you a special "guest card". With that card, you can enter the conference area, leave it, and come back whenever you want. You don't have to give all of your personal information over and over again, nor show your ticket and ID. How is that? It all thanks to the "guest card". Now think, what if there were no tickets nor "ID cards" for such events. Then you would have to prove your credentials in a very tedious way, every time you enter the area. &lt;/p&gt;

&lt;p&gt;In terms of web applications, this situation is not very different. Some of the paths on various websites are visible only for the registered users. It would be very impractical to ask the user to log in on each different route.  One of the solutions can be storing cookies and sending them back and forth between the client and the server. Another way is called authorization token. To be more precise, &lt;em&gt;JWT - JSON Web Token&lt;/em&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  JWT
&lt;/h3&gt;

&lt;p&gt;These days, JWT tokens became one of the most popular and practical ways of authenticating users. So what are those JWT tokens? It is nothing else than a long string with the encoded data, that can be decoded on the server-side. Each JWT token consists of 3 main parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Header: type of algorithm&lt;/li&gt;
&lt;li&gt;Payload: additional data&lt;/li&gt;
&lt;li&gt;Signature: verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT tokes have two main purposes, and those are &lt;strong&gt;Authorization&lt;/strong&gt; and &lt;strong&gt;Information Exchange&lt;/strong&gt;. For example, when the user logs in on our website, JWT tokes is generated by the server, added to the given user in the database, and sent back to the client. On the client-side, we can store the JWT token in the localstorage for example and add it to headers in form of &lt;code&gt;Authorization: Bearer &amp;lt;JWT Token&amp;gt;&lt;/code&gt;&lt;br&gt;
In this case, we can easily authenticate the user, and also decided whether we should give access to the given route or not. &lt;/p&gt;
&lt;h3&gt;
  
  
  Coding Time
&lt;/h3&gt;

&lt;p&gt;In the previous tutorials, we were building a very simple REST API server for storing users in the Mongo database. That is why, in this tutorial, we will use the same code and extend it with an additional feature. However, if you have your code it is also OK to just implement the given parts inside of your code. Let's open the code editors and start coding.&lt;/p&gt;

&lt;p&gt;First of all, we will have to install JWT dependency, with the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i jsonwebtoken&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Later, inside of the user schema, we will need another field for the token itself.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;accessToken: { type: String, default: null }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After adding the dependency and &lt;code&gt;accessToken&lt;/code&gt; field to the model, we are ready to move on. In the "middlewares" folder, create a new file called "generateJWT.js".&lt;/p&gt;

&lt;p&gt;The code should look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jwt from "jsonwebtoken";
import dotenv from "dotenv";
dotenv.config();

const options = {
  expiresIn: "24h",
};

async function generateJWT(username) {
  try {
    const payload = { username };
    const token = await jwt.sign(payload, process.env.JWT_SECRET, options);
    return { error: false, token };
  } catch (error) {
    return { error: true };
  }
}

export default generateJWT;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our function will take one parameter and it will be the username, that will be added to the payload. You may have also realised that we need a &lt;em&gt;SECRET&lt;/em&gt; to sign the JWT token. Since it's very sensitive data, it's better to keep it inside of the ".env" file. Inside of the .env file, add a variable called &lt;code&gt;JWT_SECRET="&amp;lt;your secret string&amp;gt;"&lt;/code&gt; and add a secret string of your own preference.&lt;/p&gt;

&lt;p&gt;Great, so now our JWT token generating function is ready and everything is set up. Let's add the functionality inside of the "login" method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { error, token } = await generateJWT(user.username);

      if (error) {
        return res.status(500).json({
          error: true,
          message: "Couldn't create access token. Please try again later.",
        });
      }

      user.accessToken = token;

      await user.save();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the code above, right after comparing the passwords. On each of the login, the server will generate a new JWT token, add it to the user object and save it in the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate Token Middleware
&lt;/h3&gt;

&lt;p&gt;So far we can log in and create a new JWT token, but where can we use it now? For example, we can protect given routes with a JWT token or execute some actions based on the JWT token. But before we do that, we have to check if the JWT token is real and valid. To make it happen, we will add validateToken middleware, in between the route and controller.&lt;/p&gt;

&lt;p&gt;Inside of the "middlewares" folder, create a new file called "validateToken.js" and add the following code inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jwt from "jsonwebtoken";
import dotenv from "dotenv";
dotenv.config();

import User from "../models/user.model.js";

async function validateToken(req, res, next) {
  const auhorizationHeader = req.headers.authorization;
  let result;

  if (!auhorizationHeader) {
    return res.status(401).json({
      error: true,
      message: "Access token is missing",
    });
  }

  const token = req.headers.authorization.split(" ")[1];

  const options = {
    expiresIn: "24h",
  };

  try {
    let user = await User.findOne({
      accessToken: token,
    });

    if (!user) {
      result = {
        error: true,
        message: "Authorization error",
      };

      return res.status(403).json(result);
    }

    result = jwt.verify(token, process.env.JWT_SECRET, options);

    if (!user.username === result.username) {
      result = {
        error: true,
        message: "Invalid token",
      };

      return res.status(401).json(result);
    }

    req.decoded = result;

    next();
  } catch (error) {
    console.error(error);

    if (error.name === "TokenExpiredError") {
      return res.status(403).json({
        error: true,
        message: "Token expired",
      });
    }

    return res.status(403).json({
      error: true,
      message: "Authentication error",
    });
  }
}

export default validateToken;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short, firstly we check whether the JWT token is present in the headers, then we split the string and take the token itself (therefore split method). After that, we check is there any user with a given token inside of the database, and did it expire or not. If everything is OK, then decoded token is added to the request part, and our middleware calls "next()" to move on to the next middleware or controller method.&lt;/p&gt;

&lt;p&gt;Where can we use it now? First of all, we can add a third method to our controller called "logout", so that we can erase the JWT token on the logout.&lt;/p&gt;

&lt;p&gt;Go to the UserController.js file and add method "logout":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async logout(req, res) {
    try {
      const { username } = req.decoded;

      let user = await User.findOne({ username });

      user.accessToken = "";

      await user.save();

      return res.status(200).json({
        success: true,
        message: "User logged out",
      });
    } catch (error) {
      console.error(error);
      return res.status(500).json({
        error: true,
        message: error,
      });
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can move back to the routes and add the last missing part, which is naturally the logout route. The whole &lt;code&gt;usersRouter.js&lt;/code&gt; file should look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import UsersController from "../controllers/UsersController.js";
const usersRouter = express.Router();

import cleanBody from "../middlewares/cleanBody.js";
import validateToken from "../middlewares/validateToken.js";

const users = new UsersController();

usersRouter.post("/signup", cleanBody, users.signup);

usersRouter.patch("/login", cleanBody, users.login);

usersRouter.patch("/logout", validateToken, users.logout);

export default usersRouter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all! You can turn on the server, open Postman and check the new routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;JWT tokens are a crucial part of any serious application, with the ready code you can extend it to many other routes and methods. Feel free to modify the code, and add your own parts. There are still a few missing parts, like unit testing, security issues, CORS or connecting the backend with the frontend. Stay tuned for more and let me know if you have some questions or suggestions.&lt;/p&gt;

</description>
      <category>node</category>
      <category>jwt</category>
    </item>
    <item>
      <title>Users Database with Login and Signup Functions from Scratch (Node.js, MongoDB)</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Mon, 12 Jul 2021 10:09:41 +0000</pubDate>
      <link>https://dev.to/pawel/users-database-with-login-and-signup-functions-from-scratch-node-js-mongodb-514c</link>
      <guid>https://dev.to/pawel/users-database-with-login-and-signup-functions-from-scratch-node-js-mongodb-514c</guid>
      <description>&lt;p&gt;Recently in one of my tutorials, you could read how to create a super simple REST API using Node.js and Express, and if you have missed that one you can find it &lt;a href="https://dev.to/pawel/how-to-build-restful-api-using-node-js-3dpp"&gt;here&lt;/a&gt;. But what is the purpose of having REST API without any database? In this tutorial, we will focus on adding MongoDB to REST API from the previous tutorial and build a simple user database with signup and login functions. &lt;/p&gt;

&lt;p&gt;One of the most traditional paths, in this case, would be to create an SQL type of database, configure a local server, and add some  &lt;a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping" rel="noopener noreferrer"&gt;ORM&lt;/a&gt; layer for establishing communication between the API and database. Additionally, we should also learn at least the basic syntax of SQL and find a way to host our database on a public server. Fortunately, there is also an alternative way to stay within JavaScript "comfort zone" and minimize the configuration part. It's all thanks to NoSQL databases, and to be more precise MongoDB.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mongo - NoSQL DB
&lt;/h1&gt;

&lt;p&gt;MongoDB is a NoSQL type of database, or in other words non-relational database. What does it mean? In traditional SQL based databases, we have tables, rows and columns, where every piece of data is strictly related to each other, and we need a specific query language (SQL) to manipulate data inside of them. NoSQL, databases are more or less like &lt;a href="https://www.json.org/json-en.html" rel="noopener noreferrer"&gt;JSON&lt;/a&gt; documents, which do not have to be related to each other or structured in a similar way. Moreover, if you are familiar with JavaScript objects, then reading and saving documents to MongoDB is almost the same as creating objects in plain JavaScript. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mongoose
&lt;/h3&gt;

&lt;p&gt;So in the previous part,  it was said that SQL databases need ORM while there is no such a need for NoSQL databases, but it doesn't mean that we cannot implement similar logic inside of NoSQL databases. Thanks to the Mongoose library, it is possible to use a similar pattern to ORM, called ODM (Object Data Modelling). Mongoose helps us organize our data, and also comes with some ready functions for connecting with MongoDB. That is all you need to know for the time being.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up MongoDB account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to the official &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new account (free is fine)&lt;/li&gt;
&lt;li&gt;Go to MongoDB Atlas Cloud&lt;/li&gt;
&lt;li&gt;Create a new project&lt;/li&gt;
&lt;li&gt;Once your project is ready click DATA STORAGE =&amp;gt; Clusters =&amp;gt; Build a Cluster&lt;/li&gt;
&lt;li&gt;Pick the free option: "Shared Cluster"
Now depending on your location, you can select the nearest server to your current location
Optionally you can change the cluster name at the bottom in this case we will call it "REST"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2vmqpibm4eobopfs9z88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2vmqpibm4eobopfs9z88.png" alt="Shared Cluster" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on "Create Cluster" and wait approximately 5 mins while the cluster is being created.&lt;/li&gt;
&lt;li&gt;Once it's ready click "Collections" and "Add My Own Data"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fekaxcthgym8fuqg3k260.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fekaxcthgym8fuqg3k260.png" alt="add data" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Give a name to a new collection created inside of the cluster (DatabaseName: restapi, Collection Name: users)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbhfi5wnz8m11950cbrwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbhfi5wnz8m11950cbrwj.png" alt="New collection" width="800" height="794"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Database Access and "Create new user"&lt;/li&gt;
&lt;li&gt;Save the password and username in a safe place&lt;/li&gt;
&lt;li&gt;Go to Network Access and click "Add IP Address" &lt;em&gt;normally you will want to give access to your database only from the backend's IP so that no one else can modify your DB, but in this case, we will whitelist all of the IP address to possible confusion&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Click "Allow access from anywhere"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvlh6v3jt064d0v41kjmx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvlh6v3jt064d0v41kjmx.png" alt="Allow access from anywhere" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go back to Clusters and leave your tab open&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now our MongoDB is ready, and we can focus on writing the code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coding Time
&lt;/h1&gt;

&lt;p&gt;It's finally time to go back to our Node.js app and open the code editor. Feel free to use the boilerplate code from the previous tutorial or just code along. &lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting MongoDB to Node.js Server
&lt;/h3&gt;

&lt;p&gt;1 Open the folder of the project and install mongoose &lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i mongoose&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2 Import Mongoose inside of the "app.js" file &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import mongoose from "mongoose";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3 Create a connection with MongoDB via mongoose.connect method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongoose
  .connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useFindAndModify: false,
  })
  .then(() =&amp;gt; {
    console.log("Database connection established");
  })
  .catch((err) =&amp;gt; {
    console.error(`ERROR: ${err}`);
 }); 

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

&lt;/div&gt;



&lt;p&gt;As you may see, the first parameter of connect function is the address of our MongoDB database, which should be stored inside of the .env file for the security precautions&lt;/p&gt;

&lt;p&gt;4 Inside of the .env file create a new variable called MONGO_URI&lt;/p&gt;

&lt;p&gt;5 Go back to MongoDB tab and click on "Connect", select the second option called "Connect your application"&lt;/p&gt;

&lt;p&gt;6 Then you should see connection link to your database, that looks more or less like that "mongodb+srv://user:@rest.cr5aa.mongodb.net/myFirstDatabase?retryWrites=true&amp;amp;w=majority"&lt;/p&gt;

&lt;p&gt;7 Copy and paste this string inside of the .env file like that &lt;/p&gt;

&lt;p&gt;&lt;code&gt;MONGO_URI="mongodb+srv://admin:&amp;lt;password&amp;gt;@rest.cr4bo.mongodb.net/myFirstDatabase?retryWrites=true&amp;amp;w=majority"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;8 Change &lt;code&gt;&amp;lt;password&amp;gt;&lt;/code&gt; part with your password, and &lt;code&gt;myFirstDatabase&lt;/code&gt; with the collection name that we gave before in this case it was "restapi"&lt;/p&gt;

&lt;p&gt;Now you can go to the terminal and type &lt;code&gt;npm start&lt;/code&gt;, hopefully, everything went smoothly and you should see text in the console saying "Database connection established".  Congratulations! If you can see it, we can start adding users to our database.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In case you get an error: ERROR: Error: querySrv ESERVFAI, just wait a little bit a try again later&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  users Route
&lt;/h3&gt;

&lt;p&gt;1 First of all let's create a new file in the folder "routes" called "usersRouter.js", and then import it inside of the "app.js" file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import usersRouter from "./routes/usersRouter.js";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2 At the bottom of the file, before &lt;code&gt;app.listen&lt;/code&gt; add the following line&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.use("/users", usersRouter);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's all for the "app.js" file part, the rest of the logic will be transferred to the usersRouter file.&lt;/p&gt;

&lt;p&gt;3 Inside of the usersRouter.js file import Express Router and export the module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
const usersRouter = express.Router();

export default usersRouter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we don't have any routes yet, and also as you may remember from the previous tutorial, each route will use the controller and other middlewares so that our app will go even further.&lt;/p&gt;

&lt;p&gt;4 Inside of "controllers" folder create a new file called "UsersController.js" with an empty class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UsersController {
}

export default UsersController;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 Remember ODM? Before we start right our controller logic, we also have to create some kind of schema for the user profile. Inside of the main folder, create a new folder called "models" and inside of the models create a file called "user.model.js".&lt;/p&gt;

&lt;p&gt;6 Open user.model.js file, and there we will create an example for our MongoDB, how a user document should look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mongoose from "mongoose";

const Schema = mongoose.Schema;

const userSchema = new Schema(
  {
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
  },
  {
    timestamps: {
      createdAt: "createdAt",
      updatedAt: "updatedAt",
    },
  }
);

const User = mongoose.model("user", userSchema);

export default User;

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

&lt;/div&gt;



&lt;p&gt;7 Now it's time to go back to the UsersController.js file and import the User schema &lt;code&gt;import User from "../models/user.model.js";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;8 At this point we can add a method for signing up the users. First of all, we create a new async method with request and result parameters. The method will firstly look for an existing user in our database, in case the username is already taken it will return and send back status "400". Otherwise, it will use User schema to create a new user based on the "body" input and save it in the database. As a result, we can see the details of our newly created user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import User from "../models/user.model.js";

class UsersController {
  async signup(req, res) {
    try {
      let user = await User.findOne({
        username: req.body.username,
      });

      if (user) {
        return res.status(400).json({
          error: true,
          message: "Username is already in use",
        });
      }

      user = new User(req.body);

      await user.save();

      return res.status(201).send(user);
    } catch (error) {
      console.error(error);
      return res.status(500).json({
        error: true,
        message: "Cannot Sign up",
      });
    }
  }
}

export default UsersController;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9 Go back to the usersRouter.js file,&lt;br&gt;
import and create a new instance of UsersController class, add a new "POST" route and add the given method from the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import UsersController from "../controllers/UsersController.js";
const usersRouter = express.Router();

const users = new UsersController();

usersRouter.post("/signup", users.signup);

export default usersRouter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10 Start up the application with &lt;code&gt;npm start&lt;/code&gt; and open &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;11 Inside of the Postman, add new request, select method as POST, the address should be &lt;code&gt;http://localhost:5000/users/signup&lt;/code&gt;, click on the "Body" tab, select type "raw" and "JSON" then add the body for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
"username": "John",
"password": "doe"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click "Send" and you should see the newly created object right under the body input area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgkur1esl5p266iqudiiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgkur1esl5p266iqudiiq.png" alt="Postman result" width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are almost there! But as you can see there are huge security issues, as we can see each user's password, there is no validation etc. &lt;/p&gt;

&lt;h3&gt;
  
  
  Bcrypt
&lt;/h3&gt;

&lt;p&gt;Bcrypt is a popular library that helps us to hash different values, and also compare them later. In fact, there are two libraries called "Bcrypt" and "Bcryptjs" there are some slight differences between them. Probably Bcrypt will be a better option, but for the time being let's stick to the JavaScript version as it is easier to set up.&lt;/p&gt;

&lt;p&gt;1 Install bcryptjs in your project&lt;br&gt;
 &lt;code&gt;npm i bcryptjs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2 Create new folder "helpers" in the "controllers" folder.&lt;/p&gt;

&lt;p&gt;3 Create two files called "hashPassword.js" and "comparePasswords.js".&lt;/p&gt;

&lt;p&gt;The names are kind of self-explanatory, indeed the functions themselves are not very complicated neither. The only tricky thing may be the &lt;code&gt;genSalt(10)&lt;/code&gt; part, which specifies how much your input will be encrypted. The higher value in the first parameter, the more encrypted password will be. However, it may reflect on the overall performance so you can leave it at 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// hashPassword.js
import bcrypt from "bcryptjs";

const hashPassword = async (password) =&amp;gt; {
  try {
    const salt = await bcrypt.genSalt(10);
    return await bcrypt.hash(password, salt);
  } catch (error) {
    throw new Error("Hashing failed", error);
  }
};

export default hashPassword;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// comparePasswords.js

import bcrypt from "bcryptjs";

const comparePasswords = async (inputPassword, hashedPassword) =&amp;gt; {
  try {
    return await bcrypt.compare(inputPassword, hashedPassword);
  } catch (error) {
    throw new Error("Comparison failed", error);
  }
};

export default comparePasswords;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4  Import functions in the UsersController.js file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import hashPassword from "./helpers/hashPassword.js";

import comparePasswords from "./helpers/comparePasswords.js";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we will keep inital user's object in the "user" variable, then we will hash the password from the body, change it in the user object and in the end create new mongoose model and save it in the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; user = req.body;

      const hashedPassword = await hashPassword(req.body.password);

      user.password = hashedPassword;

      const newUser = new User(user);

      await newUser.save();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all, you can try running the app again, and check the results this time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwsbfhxipv5qacbvpo1vz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwsbfhxipv5qacbvpo1vz.png" alt="Encrypted Password" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Login Function
&lt;/h3&gt;

&lt;p&gt;Currently, we have only one route in the usersRouter.js file, let's add another one for the login purpose.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;usersRouter.post("/login",  users.login);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As we have the route, we also have to add a method that will compare the passwords and do something on hitting that API endpoint.&lt;/p&gt;

&lt;p&gt;We will look for the user in the database and return the corresponding response. Then compare the password from the "body" request and the user's object. If everything is OK, our controller will return status 200 and a success message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async login(req, res) {
    try {
      let user = await User.findOne({ username: req.body.username });

      if (!user) {
        return res.status(404).json({
          error: true,
          message: "Account not found",
        });
      }

      const isValid = await comparePasswords(req.body.password, user.password);

      if (!isValid) {
        return res.status(400).json({
          error: true,
          message: "Invalid password",
        });
      }

      return res.status(200).send({
        success: true,
        message: "User logged in successfully",
      });
    } catch (error) {
      console.error(error);
      return res.status(500).json({
        error: true,
        message: "Couldn't login. Please try again.",
      });
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sanitizing Input
&lt;/h3&gt;

&lt;p&gt;Hopefully one day our app will grow bigger, and we will have a lot of users. Popularity though is unfortunately also related to some risks. At some point, some malicious users, may try to modify our database, and since now we do not validate the input, let's add some extra middleware before adding the users to our database.&lt;/p&gt;

&lt;p&gt;Create "middlewares" folder in the main directory, and in the middlewares, folder create a new file called "cleanBody.js". &lt;/p&gt;

&lt;p&gt;Install "mongo-sanitize" package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i mongo-sanitize&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;cleanBody.js file should look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sanitize from "mongo-sanitize";

const cleanBody = (req, res, next) =&amp;gt; {
  try {
    req.body = sanitize(req.body);
    next();
  } catch (error) {
    console.log("clean-body-error", error);
    return res.status(500).json({
      error: true,
      message: "Could not sanitize body",
    });
  }
};

export default cleanBody;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import cleanBody middleware and add in between the route and controller parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import UsersController from "../controllers/UsersController.js";
const usersRouter = express.Router();

import cleanBody from "../middlewares/cleanBody.js";

const users = new UsersController();

usersRouter.post("/signup", cleanBody, users.signup);

usersRouter.post("/login", cleanBody, users.login);

export default usersRouter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try again running the app, logging, registering etc. Everything should work just like before, but this time we added an extra security layer.&lt;/p&gt;

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

&lt;p&gt;Congratulations! It was quite a lot of work, and our REST API finally starts to look like a real REST API, plus deals with some real-world problems. However, there is a still long way to go and many improvements have to be added. Feel free to modify the code and add your own features. In the next article, we will move even further and add JWT token support.&lt;/p&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Create Minimalistic REST API using Node.js and Express</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Sat, 10 Jul 2021 19:58:45 +0000</pubDate>
      <link>https://dev.to/pawel/how-to-build-restful-api-using-node-js-3dpp</link>
      <guid>https://dev.to/pawel/how-to-build-restful-api-using-node-js-3dpp</guid>
      <description>&lt;h2&gt;
  
  
  What is REST API?
&lt;/h2&gt;

&lt;p&gt;Nowadays, the word &lt;strong&gt;API&lt;/strong&gt; becomes more and more popular as we live in the era of the Information Age. Doesn't matter if you are a coder or not, probably you have heard the word &lt;strong&gt;API&lt;/strong&gt; at least a couple of times. Especially if you are a coder, APIs are all around code in many different forms, therefore it's good to know something about them. Indeed there are many different types of APIs, and the word API stands for &lt;em&gt;application programming interface&lt;/em&gt;, while REST means &lt;em&gt;representational state transfer&lt;/em&gt;, and this type of API will be the main focus of this article. Don't worry if those words do not mean too much to you at this point. So what are APIs and what do we need them for? Think of APIs as microprograms or microservices, which are a kind of bridge that connects two abstract lands. Sometimes they may live on the external server, and work as a separate program. &lt;strong&gt;REST API&lt;/strong&gt; is the best example in this case, as it is generally hosted on a separate server and serve our app on the frontend side. For instance, let's say that we have an application that manages doctors appointments, we can create the whole visual part of the ap on the front part, but what about the database and the whole logic related to communication with the database, registering users, authenticating them, and so on? In this case, we will need REST API which will take care of all of the logic related to storing data, accessing given routes, as well as security issues. Before we move on to building the REST API itself, there is one more question. How does the frontend app communicate with the backend (in this case REST API)? Just like we humans have different languages, and English is our "lingua franca", web applications have their own "international" language as well.&lt;/p&gt;

&lt;p&gt;In order to understand it, there are few core concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2122604/what-is-an-endpoint" rel="noopener noreferrer"&gt;API endpoints&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods" rel="noopener noreferrer"&gt;HTTP request methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" rel="noopener noreferrer"&gt;HTTP response codes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" rel="noopener noreferrer"&gt;Headers&lt;/a&gt; &lt;strong&gt;Optional&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages" rel="noopener noreferrer"&gt;Body&lt;/a&gt; &lt;strong&gt;Optional&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will not go over the details, but I recommend you to go over the definitions on MDN. To sum up, we can say that we can communicate with REST API via &lt;strong&gt;API Endpoints&lt;/strong&gt; which are just links with specific endings, therefore word "endpoint", plus we also have to specify &lt;em&gt;request method&lt;/em&gt; and as a result, we get some data with &lt;em&gt;response code&lt;/em&gt; from the server. Additionally, some extra details such as cookies, or authorization details can be added in &lt;strong&gt;headers&lt;/strong&gt;, while longer messages are generally put in the &lt;strong&gt;body&lt;/strong&gt; part of the request. Moreover, since these ways of communication are always more or less the same, there is no need to worry about what specific technology was used on the frontend or backend side. That is why we can see frontend applications written in JavaScript, while backend servers run very often on different languages such as C#, PHP or Java. However, since the invention of Node.js, we can now also use JavaScript on the backend side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node.js and Express
&lt;/h2&gt;

&lt;p&gt;After the short theoretical introduction to what are APIs and how do web applications work, now it's time to dig a little bit deeper. In this article we will use only JavaScript to build REST API, therefore it's good to know a few things about it beforehand. &lt;strong&gt;Node.js&lt;/strong&gt; is a program written in C++ that runs the V8 engine of JS (the same that runs inside of Google Chrome web browser), and thanks to this invention we can run JavaScript applications outside of the browser. In other words, normally we have to attach JS scripts to HTML files, which are parsed later by web browsers. However, thanks to Node.js, it is possible to write JavaScript pretty much anywhere, and run it with the help of Node.js. There are of course a few differences between the browser environment and Node.js environments, such as the lack of DOM or window object, but from the other side, we get access to the local files, and more complex operations just like with any other programming languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Express
&lt;/h3&gt;

&lt;p&gt;It is very easy to guess that thanks to the power of Node.js we can do a lot of things with JavaScript, but things can grow very complex and get out of hand very quickly. Just like on the frontend side, almost nobody is using vanilla JavaScript anymore, for the sake of &lt;strong&gt;Not Repeating Ourselves&lt;/strong&gt;, the same thing applies to Node.js and backend practices. When on the frontend we use a lot of tools, frameworks, and libraries such as React, Vue, or Angular, also here there are similar tools. One of the most popular frameworks in terms of Node.js is Express. It is kind of a small library that helps us write less verbose code and makes things even easier. It's not opinionated and you can use it just like an additional library. In this article, we will use both Node.js with Express framework to make the code as much readable as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello API World
&lt;/h2&gt;

&lt;p&gt;Let's finally move on to the coding part, but beofore starting we will need a few tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Code Editor (for example: &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS CODE&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;web browser&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; &lt;strong&gt;Optional&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First of all, download and install Node.js (there may be some differences depending on what OS you use). Anything over 12 should be OK with this tutorial. Once you have Node.js installed on your computer, you can check if everything is OK by going to the terminal and typing &lt;code&gt;node -v&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next step is to create a folder and initiate a configuration file called (package.json). If you use Linux or macOS, then you can use these commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;mkdir restapi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd restapi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;touch app.js&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The commands may differ depending on the system, but the idea is to create a new folder called "restapi", open that folder and initiate an entry file to our project called "package.json" with the flag &lt;code&gt;-y&lt;/code&gt; which simply means answers "yes" to all of the questions. If you skip this flag, then you will have to answer them manually. In the last part, we create the file &lt;code&gt;app.js&lt;/code&gt; where our API's code will live.&lt;/p&gt;

&lt;p&gt;After creating the folder, and necessary files open the code editor and go to the given folder. The first modification will be to add one line to the &lt;code&gt;package.json&lt;/code&gt; file, which will let us use ES6 way of importing modules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; // "commonjs" style

const express = require("express");

// ES6 style
import express from "express";

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

&lt;/div&gt;



&lt;p&gt;To enable this option, open &lt;code&gt;package.json&lt;/code&gt; file and under &lt;code&gt;"description"&lt;/code&gt; add the following line &lt;/p&gt;

&lt;p&gt;&lt;code&gt;"type": "module",&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Additionally, you can also add the following line &lt;/p&gt;

&lt;p&gt;&lt;code&gt;"start": "node app"&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;inside of the &lt;code&gt;"scripts"&lt;/code&gt; block. This will let you use &lt;code&gt;npm start&lt;/code&gt; command just like you have probably used before with React for example, otherwise you would have to type &lt;code&gt;node app&lt;/code&gt; each time in the terminal to execute &lt;code&gt;app.js&lt;/code&gt; file with Node.js. There is one more detail - Express. Go to the terminal, make sure that your terminal is opened inside of the project folder and type in the following command &lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i express&lt;/code&gt; - this command means use the npm package manager, and &lt;code&gt;i&lt;/code&gt; install the package called &lt;code&gt;express&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Before we had to write &lt;code&gt;install&lt;/code&gt; instead of &lt;code&gt;i&lt;/code&gt; and also add the flag &lt;code&gt;--save&lt;/code&gt; to add the module to the package.json file.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now inside of "app.js" file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import Express framework &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;import express from "express";&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initiate express inside of variable called app&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;const app = express();&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add one route "/", and only one method "GET".
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
app.get("/", (req, res) =&amp;gt; {
  res.send("hello world");
});

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

&lt;/div&gt;



&lt;p&gt;First of all inside of the app object, we have method &lt;code&gt;.get&lt;/code&gt; which takes 2 parameters &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"/" string which is the route on which will it listen,&lt;/li&gt;
&lt;li&gt;(req, res) callback function with two parameters &lt;code&gt;req - request&lt;/code&gt; and &lt;code&gt;res - result&lt;/code&gt;. Since we do not care much about the request at this point, just hitting the endpoint with the "GET" method, we will only send back string "hello world" back to the sender.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;It's time to start our server and set it to listen on a given port.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;app.listen(5000);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Method listens, starts our server, and its first parameter is the value of the port that our app will listen on - in this case: 5000, but feel free to change it to the other values.&lt;/p&gt;

&lt;p&gt;The overall code should look like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import express from "express";

const app = express();

app.get("/", (req, res) =&amp;gt; {
  res.send("hello world");
});

app.listen(5000);

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

&lt;/div&gt;



&lt;p&gt;Now you can type in &lt;code&gt;npm start&lt;/code&gt; or &lt;code&gt;node app&lt;/code&gt; in the terminal, open your web browser and go to the &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;. On that address "hello world" text should be visible. &lt;/p&gt;

&lt;p&gt;You can also do the same with Postman, by sending GET request to that address&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To terminate the server, hit &lt;code&gt;CTRL + C&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's all! Congratulations! :) Our first very simple REST API is ready. But in real life, it is not enough as there are many other things to learn and improve.&lt;/p&gt;

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

&lt;p&gt;It is almost finished, we won't any extra functionality to this app. Before finishing let's refactor our code a little bit more and introduce some very simple design patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Middleware
&lt;/h3&gt;

&lt;p&gt;Middleware, like the name can suggest is some kind of software or let's call it method that runs in the middle of our requests and responses. There are many middlewares that you may want to end up adding to your app, but for now, we will need some absolute basics.&lt;/p&gt;

&lt;p&gt;Right after &lt;code&gt;const app = express();&lt;/code&gt; add following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use(express.json());
app.use(express.urlencoded());

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

&lt;/div&gt;



&lt;p&gt;Method &lt;code&gt;.use&lt;/code&gt; is generally used to add middlewares for the connections made with the express, in this case, we have &lt;code&gt;.json()&lt;/code&gt; and &lt;code&gt;.urlencoded&lt;/code&gt;. These two middlewares will parse JSON files and convert request input, to readable strings and numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  process.env
&lt;/h3&gt;

&lt;p&gt;Since the backend side is always much more vulnerable to hacker attacks, as it may store very sensitive information such as passwords to the databases etc. It's better to take some precautions and never share those kinds of values in the public repositories. That is why we use environmental config files, such as &lt;code&gt;.env&lt;/code&gt;. Let's store our port value inside of such an environmental file.&lt;/p&gt;

&lt;p&gt;First of all, we will need to download the npm package for this purpose use &lt;/p&gt;

&lt;p&gt;`npm i dotenv',&lt;/p&gt;

&lt;p&gt;then import it with &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import dotenv from "dotenv";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and set it up with the following line &lt;code&gt;dotenv.config();&lt;/code&gt;. Now you can create a new file called &lt;code&gt;.env&lt;/code&gt; inside of the same folder. Inside of the &lt;code&gt;.env&lt;/code&gt; file add the following line &lt;code&gt;PORT=5000&lt;/code&gt;. Then go back to the &lt;code&gt;app.js&lt;/code&gt; file, create a variable called port and assign it to the value from the &lt;code&gt;.env&lt;/code&gt; file like that &lt;code&gt;const port = process.env.PORT;&lt;/code&gt; Now you can modify the last line of the code to &lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.listen(port);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will enable us to change port values dynamically, depending on the given server. You can also add a callback as a second parameter.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
app.listen(port, () =&amp;gt; {&lt;br&gt;
  console.log(&lt;/code&gt;Listening on port: ${port}&lt;code&gt;);&lt;br&gt;
});&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Express Router
&lt;/h2&gt;

&lt;p&gt;REST API can grow very big and complex, so it is better to keep the routes outside of the main file. Let's create a separate folder for the given routes, and add a file called "mainRouter.js". Inside of this file, we will use again Express, but this time it's the Router method that helps to reroute between different paths easily.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
import express from "express";&lt;br&gt;
import MainController from "../controllers/MainController.js";&lt;br&gt;
const mainRouter = express.Router();&lt;/p&gt;

&lt;p&gt;const mainController = new MainController();&lt;/p&gt;

&lt;p&gt;mainRouter.get("/", mainController.HelloWorld);&lt;/p&gt;

&lt;p&gt;export default mainRouter;&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Controller
&lt;/h2&gt;

&lt;p&gt;Most of the code should be clear by now, but you may be wondering what is "MainController"? The more routes we have in our app, the more logic to handle each route we have, so let's go a bit further and divide this part as well. In the main folder, create a folder called "controllers" and there create a new file called "MainController.js". Inside of this file, create class with a public method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
class MainController {&lt;br&gt;
  HelloWorld(req, res) {&lt;br&gt;
    return res.send("Hello World");&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
export default MainController;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Almost there! Now we can also edit "app.js" file so everything should look like that:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
import express from "express";&lt;br&gt;
import dotenv from "dotenv";&lt;br&gt;
import mainRouter from "./routes/mainRouter.js";&lt;/p&gt;

&lt;p&gt;dotenv.config();&lt;/p&gt;

&lt;p&gt;const app = express();&lt;/p&gt;

&lt;p&gt;const port = process.env.PORT;&lt;/p&gt;

&lt;p&gt;app.use(express.json());&lt;br&gt;
app.use(express.urlencoded());&lt;/p&gt;

&lt;p&gt;app.use("/", mainRouter);&lt;/p&gt;

&lt;p&gt;app.listen(port, () =&amp;gt; {&lt;br&gt;
  console.log(&lt;code&gt;Listening on port: ${port}&lt;/code&gt;);&lt;br&gt;
});&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can try to run it once again, everything should work just like before.&lt;/p&gt;

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

&lt;p&gt;Congratulations if you made it that far! However, it is just a beginning and there are many more things to learn about Node.js and Express. The application is super simple, but hopefully, it gave you the initial idea of how to create REST APIs in Node.js. Stay tuned for more, as in my upcoming articles, we will add new features to this API.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>express</category>
      <category>restapi</category>
    </item>
    <item>
      <title>Increase Your Productivity with YouTube and a Few Lines of JS Code</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Sat, 15 May 2021 09:43:00 +0000</pubDate>
      <link>https://dev.to/pawel/increase-your-productivity-with-youtube-and-a-few-lines-of-js-code-106l</link>
      <guid>https://dev.to/pawel/increase-your-productivity-with-youtube-and-a-few-lines-of-js-code-106l</guid>
      <description>&lt;p&gt;YouTube is a great platform that allows us to find information nearly about anything. Unfortunately, it is also a huge time waster as it can easily distract us with the proposed content or with the ads. What if we still want to use it in a possibly most productive way, without paying anything extra for subscription or premium extensions to your browser? There is a very simple solution to that problem! You can get rid of both ads and distracting content with just a few lines of code*.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This tutorial will be focused on Firefox Web Browser, but you can still apply nearly the same techniques in different web browsers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Web Browser Extension
&lt;/h1&gt;

&lt;p&gt;What is it? Most of the popular web browsers let us add extra plugins in other words called extensions. Just like you can guess, those are additional scripts that can run in the background on the selected websites or any website. In our case, we will want the script to run just when we visit YouTube. Before we move on to create the extension itself, we have to deconstruct the problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  YouTube
&lt;/h1&gt;

&lt;p&gt;First of all, when we visit the main page of YouTube, you will see a huge grid with dozens of recommended videos that can catch our attention and sometimes even very easily take us to the very wrong places ;) Let's get rid of that element first. Go to YouTube main page, and click on settings =&amp;gt; Web Developer =&amp;gt; Web Developer Tools or simply &lt;code&gt;CTRL+SHIFT+I&lt;/code&gt;, then click on the "Pick an element" button or &lt;code&gt;CTRL+SHIFT+C&lt;/code&gt;. It will let you simply hover over the given items on the website and find them easily in the code. The next step is to find some special tag name, id or class attribute of the given element so that we can hide it. Those class names and ids may change over time, so it is better to check it yourself what is the exact name at the time. In my case, at the time of writing this article, the element with a grid has a tag name name called &lt;code&gt;ytd-rich-grid-renderer&lt;/code&gt;. Then, click on the console tab &lt;code&gt;(CTRL+SHIFT+K)&lt;/code&gt; and write the following line of code &lt;code&gt;document.querySelector("ytd-rich-grid-renderer").style.display = 'none';&lt;/code&gt; click enter and the grid element shouldn't be visible anymore.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ads
&lt;/h1&gt;

&lt;p&gt;OK, so in the previous part we found a way how to get rid of the grid element, but what about ads? As you know, every ad needs a skip button, but this button may not be clickable for at least the first 5 seconds. There is another trick for this problem. You can also inspect the video player and you will quickly find out that this button is always there, but it is hidden for some amount of time. We do not need to see it even,  using DOM manipulation we can click it without showing it. At the time of writing this article, that button has a class name of &lt;code&gt;ytp-ad-skip-button&lt;/code&gt;, so each time when you see the ad you can open the console and call the following line of code &lt;code&gt;document.querySelector(".ytp-ad-skip-button").click();&lt;/code&gt; The ads are gone, but we still have the recommended videos on the side visible. The procedure for removing it is very similar to removing the grid, so if you go to the console and input the following line of code &lt;code&gt;document.querySelector("#secondary-inner").style.display = "none";&lt;/code&gt; the recommended videos bar should be gone.&lt;/p&gt;

&lt;p&gt;Everything works as it should. However, we still need to call all of the actions over and over again, and in the end, it takes even more time than watching the ads. At this moment we have to find a way to automatize this process and extensions will be helpful here. From that moment, I will strictly follow the way of creating the extension for Firefox, but for Chrome the process looks very similar. So first of all, create a new folder and name it as you wish, then inside of this folder create two files&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;manifest.json&lt;/li&gt;
&lt;li&gt;script.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open manifest.json with VS Code or any other code editor, it could be even notepad. Inside of this file, we will have to create a JSON object with a minimum of following attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "manifest_version": 2,
  "name": "nameForYourExtension",
  "version": "1.0",

  "description": "Removes ads and recommended videos from YouTube",

  "content_scripts": [
    {
      "matches": ["*://*.youtube.com/*"],
      "js": ["script.js"]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of the manifest.json, we firstly match the address on which our script will be run and in the second line we link the file with JavaScript code.&lt;/p&gt;

&lt;p&gt;That is all for manifest.json, now let's move on to the script.js file which should look something like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setInterval(() =&amp;gt; {
  (async function () {
    const skipBtn = await document.querySelector(".ytp-ad-skip-button");
    skipBtn.click();
  })();

  (async function () {
    const grid = await document.querySelector(
      "ytd-rich-grid-renderer"
    );
    grid.style.display = "none";
  })();

  (async function () {
    const side = await document.querySelector("#secondary-inner");
    side.style.display = "none";
  })();
}, 500);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we will set an interval which will be called every 500 milliseconds when we are browsing YouTube, inside this code we have 3 IFFE async functions, each one responsible for a separate element. Code is quite straightforward, we use async functions, as sometimes some elements may load later, so just to be on the safe side it is better to wait for the given element to load. Once we have it, we can execute a DOM query on each of them.&lt;/p&gt;

&lt;p&gt;Now it is time to test our new extension, go to Firefox and click on settings =&amp;gt; Add-ons Manager &lt;code&gt;(CTRL+SHIFT+A)&lt;/code&gt;, click on the gear button and select option Debug Add-ons. Then you will see a new tab with a button called "Load Temporary Add-on". Click on that button, go to the folder where you have created your add-on and open the manifest.json file. Everything should work by now, and each time you open YouTube ads and recommended videos should be gone! :) The only problem now is that, since it is not an official and approved add-on for Firefox, you will have to repeat that temporary add-on procedure each time you open firefox. Deploying add-ons to firefox is free, so you feel free to create an account and publish your extension. &lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Now you can enjoy your "free YouTube subscription" as long as you like :D  There are unfortunately some drawbacks, as even if you publish it to firefox the add-on may stop working one day due to new class names or other updates, another thing is that it won't work with official YouTube apps. Feel free to modify the code as much as you like or even add new features. Before we finish, let's answer one more potential question: why do we even bother when there are plenty of add-ons already available? There are two reasons, first for the learning purposes and having the satisfaction of creating your own add-on, the second one is security issues as we shouldn't trust every add-on since these days we can never be sure what is inside of the code.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>productivity</category>
      <category>extension</category>
    </item>
    <item>
      <title>How to Build your own RC Car with Arduino - ArduCar</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Sun, 21 Mar 2021 19:55:16 +0000</pubDate>
      <link>https://dev.to/pawel/how-to-build-your-own-rc-car-with-arduino-arducar-12ei</link>
      <guid>https://dev.to/pawel/how-to-build-your-own-rc-car-with-arduino-arducar-12ei</guid>
      <description>&lt;h1&gt;
  
  
  Electronics and Programming are not that Scary
&lt;/h1&gt;

&lt;p&gt;Most of us here, write a lot of code and very rarely have any kind of interaction with electronics, which indeed run our codes. Another thing is a common myth that electronics are very difficult to understand and that we need at least an electronic engineer title to get started with it. As a technician, petrolhead and coding enthusiast, Arduino was always somewhere on my list. I also had an RC car when I was a kid and always wanted to buy another one in my adulthood, so now when I have started learning to code, got an Arduino kit, it was the best time to make this childhood dream come true.&lt;/p&gt;

&lt;p&gt;Before and if you proceed to the next part I want to add a few more things. First of all, this is an old article that I have published before on some technical websites related to microcontrollers, so you can treat this one just as a remastered version. This tutorial is heavily based on the technical explanation, however, in the second part of the tutorial, I explain the code written in Arduino IDE. Last but not least, even though ArduCar is my own application written in Java, I have not provided the source code nor an explanation of it in this tutorial.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's have some fun!
&lt;/h1&gt;

&lt;p&gt;In this instruction, you will learn how to create an Arduino based RC car from a scratch. No prior programming, Arduino, or electronics experience needed. Even though having some previous experience in those fields can be helpful, everyone should be able to finish this project without any problems. You may also ask, why Power bank? These days, those devices are becoming more and more affordable, in some cases, they are even cheaper than batteries, many of us have them at our own houses, they can be reused, and recharged anytime we want. The project covers the basics principles of creating such a car, with a minimalistic approach on materials, and explains the code in details. Moreover, provided instructions can be also used in different projects, so let's start!&lt;/p&gt;

&lt;p&gt;As a hobbyist, I didn't have many tools like soldering iron etc. So I have tried to make use of some old electronic things such as USB cable or power bank, that most of you may have somewhere at home. You may follow all of my instructions, but feel free to change some parts and be creative. Below, the list of the materials can be found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Arduino UNO&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;car chassis, with wheels and motors, kit&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;male - male, and female - male jumper wires&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;electrical insulation tape&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bluetooth module (HC-06 or HC-05)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DC motor controller (L298N)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Power Bank with 2 USB outputs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Piezo buzzer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Android mobile phone&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PC with Arudino IDE installed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=practical.learning.arducar" rel="noopener noreferrer"&gt;ArduCar - Arduino RC Car Bluetooth Controller&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Step 1: Chassis Assembly
&lt;/h1&gt;

&lt;p&gt;First of all, we will need to assembly the chassis of our car. If you have a kit, most probably you also got the instructions with it, but just in case the steps can be found below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Prepare the main part of the chassis, 4 small plastic brackets which will mount motors on the chassis frame (2 for each), screws, brass spacers, nuts, motors, useless USB cable, and 4 cables/ jumper wires.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect one wire to each pin of a motor, you can solder them but if you don't have soldering iron, just try to "knot" the cables to each pin.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsa21ttwmyhfti0p8xiab.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsa21ttwmyhfti0p8xiab.jpeg" alt="ArduCar" width="540" height="960"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Now take your old/spare USB cable, and cut it so there is around 20 cm of cable left.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strip a few centimetres of cable covering so you can see the cables inside it; there should be 4/5 cables inside, but we are interested just in two cables, GND - black one, and Plus - Red one. Strip 2-4 cm of covering from both red and black cable. You can leave it like that, or to make it stronger just "knot" it or solder with longer, stronger cable/ jumper wires so that the connection is firm enough.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fawov3vxge8vawj64x5gp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fawov3vxge8vawj64x5gp.png" alt="ArduCar" width="219" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take the motor, and mount it to the chassis frame with plastic brackets (2 for each), using screws and nuts. Please note that, each motor has a small "dot" on one side, and that dot should face inward so that when two motors are on place, these dots face each other.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fsned7gx0j6zeasphln4s.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsned7gx0j6zeasphln4s.jpeg" alt="ArduCar" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once the motors are on their place, it is time for the 3rd nylon supporting wheel. When you look at the end of the frame, there should be 4 small holes next to each other, looking like a square shape. Take the brass spacers and mount them to these holes with screws, so brass spacers are on the same side of the frame with motors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mount the nylon supporting wheel to the brass spacers with screws.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs6u2mb6wrhffl0eq2i51.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs6u2mb6wrhffl0eq2i51.jpeg" alt="ArduCar" width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install the wheel to each motor. Note that, there is a shape inside of the wheel hub so be sure to put it in the right place. Most probably there will be a huge resistance, but you have to be gentle with it and use some power at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We are almost done with assembling the car, at this point you can install Arduino module and DC motor controller to the frame. I used 3 screws with nuts that were left from the kit and covered wires with electrical insulation tape where it was necessary.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fppkwc5hzxyl9gz3cyxnd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fppkwc5hzxyl9gz3cyxnd.jpeg" alt="ArduCar" width="287" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Wiring
&lt;/h1&gt;

&lt;p&gt;Once we have our car assembled with both Arduino and DC motor controller onboard, it is time for wiring. Prepare the jumper wires, both male - male and female - male.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take the cables that are connected to the motors and install them to the DC motor controller. Let's say that lower pins, the ones closer to the ground, are the plus pins, and the ones closer to the frame are minus (GND). The circuit should look like this:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;OUT1 - Left motor (-) GND cable&lt;/p&gt;

&lt;p&gt;OUT2 - Left motor (+) cable&lt;/p&gt;

&lt;p&gt;OUT3 - Right motor (+) cable&lt;/p&gt;

&lt;p&gt;OUT4 - Right motor (-) GND cable&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fiwzm4e4t1wolmfujzeb2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fiwzm4e4t1wolmfujzeb2.jpeg" alt="ArduCar" width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now let's connect Arduino to the DC motor controller, in order to do that, we will use pins with tiny names IN1, IN2, IN3, and IN4. Previous OUT1, 2, 3, 4 sockets were responsible for transferring the power to the electric motors, but with IN1, 2, 3, 4 pins, we will send commands to the controller from our Arduino device. This time you may need female - male wire jumpers, but if you don't have such a wire just try to modify male - male wire jumper or solder the wires to the pins.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;IN1 - DIGITAL 5&lt;/p&gt;

&lt;p&gt;IN2 - DIGITAL 6&lt;/p&gt;

&lt;p&gt;IN3 - DIGITAL 10&lt;/p&gt;

&lt;p&gt;IN4 - DIGITAL 11&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bluetooth module is the last crucial thing we will need for our steering, when you look at the Bluetooth module it should have 4 pins and each pin is signed as follows VCC - POWER, GND - Ground (-), TXD - transfer data, RXD - receive data. Female - male jumper wires may be needed once again this time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;VCC - POWER 5V&lt;/p&gt;

&lt;p&gt;GND - POWER GND&lt;/p&gt;

&lt;p&gt;TXD - DIGITAL 0 RXD&lt;/p&gt;

&lt;p&gt;RXD - DIGITAL 1 TXD&lt;/p&gt;

&lt;p&gt;As you can see, data will be exchanged between Arduino and our Bluetooth module, that is why data cables are connected in the opposite way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fp4jr5yczhzu12jv6s5t8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fp4jr5yczhzu12jv6s5t8.jpeg" alt="ArduCar" width="287" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Piezo buzzer has 2 legs, a longer one, Anode (+), and shorter one Cathode(-). It is recommended to use 330 Ohm resistor between piezo buzzer and Anode because it is a very sensitive and tiny instrument, but I didn't use one, as the resistor makes my piezo buzzer very silent. Note: Female - male wire jumpers may be helpful again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anode(+) long leg - DIGITAL 3&lt;/p&gt;

&lt;p&gt;Cathode(-) short leg - POWER GND&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fshyi4z4juo58wqty9sd9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fshyi4z4juo58wqty9sd9.jpeg" alt="ArduCar" width="680" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We are almost there! Now we need to power our Arduino board and DC motor controller. Take the USB cable part that we have prepared in the previous part and connect those two cables; red and black to DC motor controller.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Red cable (+) - 12 V&lt;/p&gt;

&lt;p&gt;Black cable (-) - GND&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The last step is to connect two USB cables, one to Power bank and Arduino board, and other one that connected to the DC motor controller, to Power bank as well. Last thing is to mount your Power bank on the frame, I used an electrical insulation tape to stick it to the frame, but there are many other ways to mount it. Note: some Power banks may have a switch or button on them, so to power the circuit you may need to switch the power on.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fx6wac043bzcz5dri2cc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fx6wac043bzcz5dri2cc2.png" alt="ArduCar" width="680" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All of the parts and wiring are on its' place, but still there is no code in Arduino and no application on the mobile phone to control the car.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Step 3: Programming
&lt;/h1&gt;

&lt;p&gt;Now that we have our RC car ready, the last part is to upload the code to the Arduino board and download the application on an Android mobile phone. For this step, you will need the Arduino IDE program on your computer, which can be downloaded from the Arduino official website. Once you have it installed, there are two options that need to be set. Open the Arduino IDE program and you will see a few options on the upper bar, pick "Tools" and then you should see the list, find the option called "Board:" and pick your Arduino board from the list (most of the time it is Arduino UNO). Later, right under the "Board:" option, click on the "Port" option, if there are no USB devices connected to your PC, it may be greyed out/disabled, once you connect your Arduino board with a USB cable this option should become available, you may have to choose one port, for example in my case it is PORT 5. Even though I have 3 USB ports on my laptop, just one of them works as a PORT. You can try with different USB sockets on your computer till it works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8f274bvs9ftz2s5e07jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8f274bvs9ftz2s5e07jt.png" alt="ArduCarIDE" width="460" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we move on to uploading the code to Arduino, you have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Just download the attached file, open it with Arduino IDE program and simply upload it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Arduino IDE program, click on File - New, copy the code from here, and click on the "Upload" icon. Remember that while uploading your code Arduino board should be connected to your PC via the right USB socket, on which the port is set.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: &lt;strong&gt;While uploading the code to Arduino, DIGITAL 0 RX, DIGITAL 1 TX sockets should be unplugged&lt;/strong&gt;, when those sockets are connected to the Bluetooth module, Arduino may not accept the incoming data from your PC and the program may freeze at "uploading" state.&lt;/p&gt;

&lt;p&gt;Below you can find the code with explanations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After uploading the code to the Arduino board, it is time to reconnect DIGITAL 0 RX and DIGITAL 1 TX pins to the Bluetooth module and reconnect the USB cable (Arduino - Power bank) to the Power bank.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;4.The last step to make your RC car work, is to download the Android application from Google Play Store, and start having fun! &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dpractical.learning.arducar" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dpractical.learning.arducar" alt="ArduCar - Arduino RC Car Bluetooth Controller Android Application" width="800" height="400"&gt;&lt;/a&gt; You may also download different applications, as long as they send the matching serial codes, or even create your own mobile application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhfp9kxhv8u0hny0zc1w2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhfp9kxhv8u0hny0zc1w2.jpeg" alt="ArduCar" width="680" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for your attention, and wish you have a lot of fun with it. In case of any questions or suggestions, please let me know about it down below in the comments section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#define in1 5
#define in2 6
#define in3 10
#define in4 11
int state;
int piezo = 3; 
void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(piezo,OUTPUT);
  Serial.begin(9600);
}
void loop() {
  if (Serial.available() &amp;gt; 0) {
    state = Serial.read();
    Stop();
    switch (state) {
      case 'F':
        forward();
        soundFX(3000.0,30+400*(1+sin(millis()/5000)));
        break;
      case 'G':
        forwardleft();
        soundFX(3000.0,60);
        break;  
      case 'D':
        forwardright();
        soundFX(3000.0,60);
        break;  
      case 'N':
        backright();
        soundFX(3000.0,30+100*(1+sin(millis()/2500)));
        break;
      case 'C':
        backleft();
        soundFX(3000.0,30+100*(1+sin(millis()/2500)));
        soundFX(3000.0,30+100*(1+sin(millis()/2500)));
        soundFX(3000.0,30+100*(1+sin(millis()/2500)));
        soundFX(3000.0,30+100*(1+sin(millis()/2500)));
        break;
      case 'B':
        back();
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        break;
      case 'L':
        left();
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        break;
      case 'R':
        right();
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        soundFX(3000.0,60);
        break;
      case 'H':
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        soundFX(3000.0,60);
        soundFX(3000.0,30+200*(1+sin(millis()/2500)));
        soundFX(3000.0,60);
    }

  }
}
void forward() {
  analogWrite(in1, 255);
  analogWrite(in3, 255);
}
void forwardleft() {
  analogWrite(in1, 50);
  analogWrite(in3, 255);
}
void forwardright() {
  analogWrite(in1, 255);
  analogWrite(in3, 50);
}
void back() {
  analogWrite(in2, 255);
  analogWrite(in4, 255);
}
void backright() {
  analogWrite(in2, 50);
  analogWrite(in4, 255);
}
void backleft() {
  analogWrite(in2, 255);
  analogWrite(in4, 50);
}
void left() {
  analogWrite(in4, 255);
  analogWrite(in1, 255);
}
void right() {
  analogWrite(in3, 255);
  analogWrite(in2, 255);
}
void Stop() {
  analogWrite(in1, 0);
  analogWrite(in2, 0);
  analogWrite(in3, 0);
  analogWrite(in4, 0);
}
void soundFX(float amplitude,float period){
 int uDelay=2+amplitude+amplitude*sin(millis()/period);
 for(int i=0;i&amp;lt;5;i++){
   digitalWrite(piezo,HIGH);
   delayMicroseconds(uDelay);
   digitalWrite(piezo,LOW);
   delayMicroseconds(uDelay);
 }
} 

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Arduino Code Explanation and Bluetooth Module Configuration (Optional)
&lt;/h1&gt;

&lt;p&gt;For the curious ones, I have decided to add an Arduino code explanation, so it may help some of you understand the mechanics and logic behind this RC car even better. I also want to add that it is not entirely my code, it is very similar to the codes that are available in different projects, I just simplified some parts and added the chunks for the Piezo buzzer sound.&lt;/p&gt;

&lt;p&gt;Arduino IDE program uses a kind of a simplified hybrid version of C and C++ programming languages, so it can remind you of those programming languages if you are familiar with them, but if not it is also OK. The code will be divided into a few chunks to help you understand it better.&lt;/p&gt;

&lt;p&gt;Each Arduino program is composed of two basic parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;void setup() { }&lt;/code&gt; - where we set a function for each of the Arduino's pin. This is something that is read by the Arduino just once, gets the information, and stores it for the rest part of the program.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In our case it looks like that:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;void setup() {pinMode(in1, OUTPUT);&lt;/code&gt; pinMode means that we will set a mode for the given pin, inside the brackets, there are two values, first one - in1, is the name of the pin that we are referring to, and the second value - OUTPUT means that we will send some data from Arduino to the target. If there is INPUT written, it means that the given pin would receive a data from a sensor etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
pinMode(in2, OUTPUT);

pinMode(in3, OUTPUT);

pinMode(in4, OUTPUT);

pinMode(piezo, OUTPUT);

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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Serial.begin(9600);&lt;/code&gt; Serial is the port that can be used for sending and receiving the data, do you remember those DIGITAL 0 RX and DIGITAL 1 TX pins that we were connecting the Bluetooth module to? It is about their setting. It means that we will open a channel through which data will be exchanged. The number inside the brackets (9600) means that in one second up to 9600 characters can be sent. It is the most frequently used baud rate, as it is the most stable one, the higher the number is, the faster it is, but also more prone to being disturbed by the noise it is. That is why just leave it at 9600. Note: Bluetooth modules are generally set to baud rate 9600 by default, but sometimes you may have to configure it before - check the Bluetooth configuration section.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;void loop() { }&lt;/code&gt; - As you can guess from the name, it is the part of the program in which everything written inside the curly brackets, will be repeated again and again. That is all, that is needed for any Arduino program to run. Rest is just your own imagination. Before I move to the details in loop and functions, there is one more part that is located at the beginning of our code, right before &lt;code&gt;void setup() { }&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the &lt;code&gt;void setup() { }&lt;/code&gt; part we have named Arduino pins as in and piezo, but those are not their real names, those are just names that we gave them, and the program will always relate to those names while executing the program. Because of that, at the beginning of each Arduino program we can initialize some names for the pins and variables. Let's have a look at our example:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;#define in1 5&lt;/code&gt;  When you want to define a name for some pin on the Arduino board you can use &lt;code&gt;#define&lt;/code&gt; word, and then write the name after space. In our case, it's in1, as it is the name of the DC motor controller pin that we are going to control. The next space is followed by the number of the given pin. In this case, it is 5 as the in1 pin is connected to the socket number 5 on the Arduino board.#define in2 6&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
#define in3 10

#define in4 11

int state; // We can also initialize names of the pin as variables int (integer), and variables itself.

int piezo = 3;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now let's move back to the loop part.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;void loop() {if (Serial.available() &amp;gt; 0) {&lt;/code&gt;  First statement in the loop starts with if, inside the brackets we can see a condition, it says &lt;code&gt;Serial.available() &amp;gt; 0)&lt;/code&gt; - simply it means, if Serial, in our case Bluetooth module, is available, greater than 0, remember the binary code 1 - true, 0 - false, do the following { } - everything in those curly braces will be executed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;state = Serial.read();&lt;/code&gt; Remember that state variable at the beginning of the code? This is the time when we assign the value to that variable ( = ) so our state variable now is equal to &lt;code&gt;Serial.read()&lt;/code&gt;, which means that the variable will change according to what is read from the Bluetooth module.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Stop();&lt;/code&gt; Those two brackets () after a name indicates that it is a function, and it has to be explained somewhere in the code. The same with this one, the first function to be executed in this code is the function named Stop, which will just literary cut off the power from the wheels and make our RC car stop.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;switch (state)&lt;/code&gt; Right after the Stop function, we have another one, this time it is the global function, that exist in nearly every programming language, and it is called switch - what literary means that there will be few functions inside, and we will just switch between them. This time you can see that inside the brackets () we have a condition, and the condition is a variable called state, which value was assigned to everything that is received from the Bluetooth module.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;case 'F':&lt;/code&gt; As you can see, each possible function inside the switch, will be marked as "case" and in the single quotations we can see the possible value of the state variable. In this case, if the state equals 'F' - such a character is sent to the Bluetooth module via the mobile application, some functions will be executed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;forward();&lt;/code&gt; The first function to be executed&lt;/p&gt;

&lt;p&gt;&lt;code&gt;soundFX(3000.0, 30+400*(1+sin(millis()/5000)));&lt;/code&gt; The second function to be executed, this time with some conditions inside the brackets.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;break;&lt;/code&gt; break means to stop executing this case, you always have to finish each case with &lt;code&gt;break;&lt;/code&gt; statement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
case 'G':

forwardleft();

soundFX(3000.0, 60);

break;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Almost everything is explained now, but there were some functions like forward(), soundFX() etc. in the code, but they were not explained in the void setup() { }, nor in the void loop() { } part of the code. If there are such functions in the code, they should be explained at the end of the code. Below you can see an example.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;void forward()&lt;/code&gt;  Again, in order to call a function firstly void should be written, and after a space, name of the function should be written, for example forward(). Inside the curly brackets we can see the explanation of the function.analogWrite(in1, 255); analogWrite means that we are sending a signal, in case we were receiving, it should be written as analogRead. Inside the brackets there are two values (in1 - the name of the pin that we are referring to, and 255 - the value of the electrical wave frequency, that can range from 0 to 255 - 0 means 0%, and 255 means 100%. It can be also written as LOW - 0, HIGH - 255. As you can see, this is the place where you can change the speed of each electric motor.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;analogWrite(in3, 255);&lt;/code&gt; In this way, we can say that by changing pins in1, 2, 3, 4, and values, we can control the side from which the electricity will enter the motors, what will be the voltage, and as a result the speed and direction.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;void soundFX(float amplitude, float period)&lt;/code&gt; This is the part that I have found on Arduino official forums, on the topic of SciFi sounds for the Piezo buzzer. You can find this code in the last post, for further explanations you can go to the link below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forum.arduino.cc/index.php?topic=118757.0" rel="noopener noreferrer"&gt;https://forum.arduino.cc/index.php?topic=118757.0&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
int uDelay=2+amplitude+amplitude*sin(millis()/period);

for(int i=0;i&amp;lt;5;i++){

digitalWrite(piezo, HIGH);

delayMicroseconds(uDelay);

digitalWrite(piezo, LOW);

delayMicroseconds(uDelay);

} }

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;It is how it works. From now on, hopefully you can also make your own contribution to the code, change something, add some new functions, or rewrite it in your own way.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bluetooth Configuration&lt;/p&gt;

&lt;p&gt;At the last, but not least, there is one more important thing to mention. HC-05 and HC-06 Bluetooth modules generally come up with default settings, such as baud rate, name, password etc. But if you would like to configure your Bluetooth module, you can use Arduino IDE program for this purpose. However, you may need to change the pins that Bluetooth module is connected to, and change Arduino code for the configuration time. Moreover, it is recommended to use resistors, in order to protect the Bluetooth module, as the data pins work at 3.3V, while the default output voltage of Arduino is 5V. Please keep all of those things in mind, I won't go throughout the whole process here, but there are plenty of tutorials available, just simply google it. If there are any suggestions, or questions please let me know in the comments' section below.&lt;/p&gt;

&lt;p&gt;Thank you for your attention once again, and don't forget to share your own projects below!&lt;/p&gt;

</description>
      <category>arduino</category>
      <category>android</category>
      <category>cpp</category>
      <category>java</category>
    </item>
    <item>
      <title>Minidoro Clock - React Native Project with FCC Background</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Tue, 09 Mar 2021 20:31:07 +0000</pubDate>
      <link>https://dev.to/pawel/minidoro-clock-react-native-project-with-fcc-background-mfm</link>
      <guid>https://dev.to/pawel/minidoro-clock-react-native-project-with-fcc-background-mfm</guid>
      <description>&lt;p&gt;This time it won't be a technical explanation, but rather a personal story with a few tips about the differences between React and React Native.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pomodoro Technique 🍅
&lt;/h1&gt;

&lt;p&gt;Let's be honest, most of us have heard of Pomodoro Technique, I bet that most of you readers also use it on a daily basis and probably a huge part of you made your own version as a project. So what is the matter? Those familiar with FCC curriculum know that project where you have to build your own version of a 25 + 5 clock, and it is where this whole story started.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Beginning
&lt;/h1&gt;

&lt;p&gt;It took me months, to finally get to that section. Each time when in vanilla JS things were starting to make sense, in React everything looked so complicated. Despite the obvious fact of React advantages, there was also React Native. A legendary framework, based on JS that lets you write mobile applications using native modules. Written once in JavaScript and compiled at the same time to both Android and iOS, sounds cool? There are of course some drawbacks, but I will not discuss them here.&lt;/p&gt;

&lt;p&gt;After finishing FCC projects, I was thinking how can I rebuild one of the projects from scratch, add some simple features and also make it at least partly meaningful for other people. Rebuilding something in your own way lets you also revise all of the things you have learned up to a certain point. The best part of building projects from scratch is that you often find yourself coming up with very interesting solutions, different from what you learned during the tutorials. It is the essence of programming, one problem - countless solutions, and one of them can be yours. This is of course positive approach, and all of you who have some experience with these kinds of projects, know how frustrating it can be sometimes. Especially when you make something that supposed to be simple, but you still struggle with a simple piece of code.&lt;/p&gt;

&lt;h1&gt;
  
  
  All right, so what is Minidoro Clock?
&lt;/h1&gt;

&lt;p&gt;Most of us care a lot about money, we are afraid of losing it and always think how to spend it or invest it right, but what about our time? There are millions of time-consuming, entertainment apps, but not as many for organizing our time. In a world full of distractions I believe that minimalism and organizing our time well should be on the top of our priority list. This is how Mindoro Clock came to my mind. Minidoro is an application where minimalism meets the Pomodoro Technique. Super simple UI and just necessary options, help us organize our time more productively.&lt;/p&gt;

&lt;p&gt;Minidoro is a simple application written in React Native, it is free and there are no advertisements. It is also open-source, so everyone can give their feedback and suggestions, or even contribute to the code of the application.&lt;/p&gt;

&lt;h1&gt;
  
  
  React + React Native
&lt;/h1&gt;

&lt;p&gt;Most probably, you can guess that the project React app, became a product landing website, to later evolve to a React Native application. The project is very simple, it barely touches some more advanced sides of React, but thanks to its simplicity it really helped me to revisit all of the core ideas behind React. Another thing is deployment, during tutorials we very rarely touch this topic, but how will other people reach your websites and applications? &lt;/p&gt;

&lt;p&gt;The first step was to make a fully functional web version of the app, commit the code to GitHub and deploy it to Netlify. Up to this point, everything went quite smooth. It was time to convert the React app to its React Native equivalent.&lt;/p&gt;

&lt;h1&gt;
  
  
  Silence before the storm
&lt;/h1&gt;

&lt;p&gt;Nothing could go wrong, overall I already had some experience with React, web development, and even some Java experience. Unfortunately, if you think that knowing all of the things above, will make your way to writing or let's say converting React apps to React Native super easy, you may be surprised. Let's make things clear, React and React Native are very similar but not the same since React mainly is meant to run in web browsers, it is just a library that runs in a Java Script environment, where React Native is a hybrid framework for running JavaScript code as a layer on a different language.&lt;/p&gt;

&lt;h1&gt;
  
  
  JSX is not the same anymore
&lt;/h1&gt;

&lt;p&gt;One of the first and main differences between React and React Native is that HTML like tags that we know from React JSX won't work with React Native. Instead, you should think of each component in JSX as a native module. Also, events are not the same, for example, there is no such thing as &lt;code&gt;onClick&lt;/code&gt; but &lt;code&gt;onPress&lt;/code&gt; instead, which indeed has a bit different behaviour. The same goes for modules, and even though some of the React modules are compatible with React Native, most of the time you will find yourself looking for a corresponding library. Because of the different behaviour of mobile devices, many modules use a lot of asynchronous functions, so if you feel rusty in this topic I recommend you to revise it before putting your hands on React Native. In the end, the environment in which we build our React Native applications is not that obvious choice, as it used to be with regular React. At this point, I can only say that if you do not have any experience with Xcode or Android Studio - Expo may be the best decision.&lt;/p&gt;

&lt;h1&gt;
  
  
  What next?
&lt;/h1&gt;

&lt;p&gt;In conclusion, redesigning React applications for React Native may not be as easy and obvious as you may think. There are a lot of things to consider, which were done somehow behind the scenes for us in the web browsers. In my case, I used Expo and haven't even touched code in Java. However, it doesn't mean that when you write React Native applications you never have to think about native code. There are many cases where React Native code, will be just a part and touch the native code may still be a must. If you want the check out my application - Minidoro Clock you can find it &lt;a href="https://minidoroclock.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please let me know if you have any questions, suggestions or found some bugs.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>reactnative</category>
      <category>android</category>
    </item>
    <item>
      <title>From Scratch to Working App - Building a React Library App</title>
      <dc:creator>LachPawel</dc:creator>
      <pubDate>Mon, 01 Mar 2021 12:32:02 +0000</pubDate>
      <link>https://dev.to/pawel/from-scratch-to-working-app-building-a-react-library-app-4bob</link>
      <guid>https://dev.to/pawel/from-scratch-to-working-app-building-a-react-library-app-4bob</guid>
      <description>&lt;p&gt;While learning web development, one of the most common patters for building projects is building a To-Do apps. Why is it like that? Most probably because this kind of applications, even though very simple, can help you review the knowledge of the core syntax and functions. There should be an event handler, some kind of state, and DOM manipulation. As a result on the web, we can find millions of To-Do apps. Why not take this idea and change it a bit to bring some fresh air into the room? That is how the Books Library App came to mind as an idea for this tutorial.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will learn how to create a React application from a scratch, commit it to GitHub and deploy it to &lt;a href="https://netlify.app/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;. I also assume that you have your development environment set up and already familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript, HTML, and CSS&lt;/li&gt;
&lt;li&gt;Basics of React (if not you can check out my &lt;a href="https://dev.to/pawel/what-is-react-how-to-use-it-and-why-react-js-basics-for-beginners-in-plain-english-3cl7"&gt;tutorial&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source code can be found &lt;a href="https://github.com/KowalewskiPawel/React-Book-Library" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the live version of the deployed app &lt;a href="https://reactbooklibrary.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  create-react-app
&lt;/h1&gt;

&lt;p&gt;First of all, create a folder for our app and start the terminal in the given folder. In the terminal type in the following command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app bookslibrary&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Of course, you can change the name of the app to whatever you like. In a couple of minutes, your project template should be ready.&lt;/p&gt;

&lt;h1&gt;
  
  
  Project Tree
&lt;/h1&gt;

&lt;p&gt;In order not to deal all the time with creating new files and folders, let us organize everything from the beginning. Your application folder tree structure should look like that&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F1pumvetmihyzz7ljn4i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F1pumvetmihyzz7ljn4i3.png" alt="project" width="699" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can delete the unnecessary files from the &lt;strong&gt;src&lt;/strong&gt; folder, leave just&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App.css&lt;/li&gt;
&lt;li&gt;App.js&lt;/li&gt;
&lt;li&gt;index.js&lt;/li&gt;
&lt;li&gt;index.css&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can erase everything from &lt;strong&gt;App.css&lt;/strong&gt;, &lt;strong&gt;App.js&lt;/strong&gt; and &lt;strong&gt;index.js&lt;/strong&gt; files, while &lt;strong&gt;index.css&lt;/strong&gt; can stay in its original form. Another part is keeping the rest of the components in &lt;strong&gt;components&lt;/strong&gt; folder. You can create 3 blank .js files inside of it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Header.js&lt;/li&gt;
&lt;li&gt;List.js&lt;/li&gt;
&lt;li&gt;Footer.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, you can also copy &lt;strong&gt;logo192.png&lt;/strong&gt; from the &lt;strong&gt;public&lt;/strong&gt; folder to the &lt;strong&gt;src&lt;/strong&gt; folder. Now we focus purely on coding our app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Roots
&lt;/h1&gt;

&lt;p&gt;Both &lt;strong&gt;index.js&lt;/strong&gt; and &lt;strong&gt;App.js&lt;/strong&gt; will have a very limited role, they will just wrap the components and delegate them to the root element in our &lt;strong&gt;index.html&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;This is how your &lt;strong&gt;index.js&lt;/strong&gt; file should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
ReactDOM.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
  document.getElementById("root")
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./App.css";
import List from "./components/List";
import Header from "./components/Header";
import Footer from "./components/Footer";
function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;Header /&amp;gt;
      &amp;lt;List /&amp;gt;
      &amp;lt;Footer /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;App component will be just a function component, and the whole logic of our application will live in the components folder. At the beginning of this file, we &lt;strong&gt;import&lt;/strong&gt; all of the components and render them inside of the App component, which is later passed to the &lt;strong&gt;index.js&lt;/strong&gt; file.&lt;/p&gt;

&lt;h1&gt;
  
  
  Components
&lt;/h1&gt;

&lt;p&gt;Let us start with the core of this application which will live in the List.js file. You can start writing this component by defining a &lt;strong&gt;class&lt;/strong&gt;, &lt;strong&gt;constructor&lt;/strong&gt; method and &lt;strong&gt;render&lt;/strong&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
export default class List extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      books: [],
    };
  }  render() {
    return (
      &amp;lt;div&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, we have only an empty class component. Inside of state, there is only one key — books, which represents an empty array. We will store the objects representing our books in that array.&lt;/p&gt;

&lt;h1&gt;
  
  
  Forms
&lt;/h1&gt;

&lt;p&gt;Our application does not render anything yet, and the first element which will be needed to register new books to the library will be the &lt;strong&gt;form element&lt;/strong&gt;. In regular HTML, forms are one of those elements which help us interact with the website, and all of the events are handled by the default by DOM, but in React we will want forms to transfer the data to React component and keep it in our &lt;strong&gt;state&lt;/strong&gt;. We will track changes in form using the &lt;strong&gt;onChange&lt;/strong&gt; attribute inside of the tags, and assign them to the handler methods.&lt;/p&gt;

&lt;p&gt;You can add the code below to the render method, inside the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form className="bookForm" onSubmit​={this.submitHandler}&amp;gt;
          &amp;lt;label for="bookName"&amp;gt;Book Title&amp;lt;/lablel&amp;gt;
          &amp;lt;input
            id="bookName"
            name="bookName"
            type="text"
            placeholder="Book Title"
            maxLength="40"
            onChange​={this.changeHandler}
            required
           /&amp;gt;
          &amp;lt;label for="bookAuthor"&amp;gt;Author&amp;lt;/label&amp;gt;
          &amp;lt;input
            id="bookAuthor"
            name="bookAuthor"
            type="text"
            placeholder="Book Author"
            maxLength="30"
            onChange​={this.changeHandler}
            required
          /&amp;gt;
          &amp;lt;label for="read"&amp;gt;Read&amp;lt;/label&amp;gt;
          &amp;lt;select
            id="read"
            name="read"
            onChange​={this.changeHandler}
            value={this.state.read}
          &amp;gt;
            &amp;lt;option value="Yes"&amp;gt;Yes&amp;lt;/option&amp;gt;
            &amp;lt;option value="No"&amp;gt;No&amp;lt;/option&amp;gt;
          &amp;lt;/select&amp;gt;
          &amp;lt;input id="submit" type="submit" value="ADD NEW
BOOK" /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every element inside of our form should be wrapped in &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, pay attention to the fact that the form itself also has an &lt;strong&gt;onSubmit&lt;/strong&gt; attribute which calls another method to submit the information from our form. In total, we have 3 &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements, each of them has attributes such as &lt;strong&gt;id&lt;/strong&gt;, &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;type&lt;/strong&gt;. There are also extra attributes inside of text input elements, and those are &lt;strong&gt;placeholder&lt;/strong&gt;, &lt;strong&gt;maxLength&lt;/strong&gt;, and &lt;strong&gt;required&lt;/strong&gt; in the end. They are kind of self-explanatory, so I will not dwell too much on them. We could skip those parts, or add them in JavaScript code, but in my opinion, code will look much cleaner like that. What is crucial here is &lt;strong&gt;onChange&lt;/strong&gt; attribute and its handler. Every time we hit change something in those fields the corresponding value in the application’s state will be updated. Moreover, look at the last option before submit button. It is &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element with two options, and we also set a default value that will be retrieved from the start every time we add a new book. Just in case someone just skips this part, it will stamp the book as not finished.&lt;/p&gt;

&lt;h1&gt;
  
  
  State
&lt;/h1&gt;

&lt;p&gt;Because we already have few references to the state, let us add missing keys in the component’s state object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(props) {
    super(props);
    this.state = {
      bookAuthor: "",
      bookName: "",
      read: "No",
      books: [],
      };
     }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all about the state part of this application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Handlers
&lt;/h1&gt;

&lt;p&gt;There is already a form where we can input the necessary data, we also have the state part ready, but there are no handler functions that can handle all of those events. Let us add them now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;changeHandler = (event) =&amp;gt; {
    const nam = event.target.name;
    const val = event.target.value;
    this.setState({
      [nam]: val,
    });};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we have 2 input text fields and 1 select, we will have to handle the change in each of them. To not to repeat ourselves (DRY) we will reuse the same handler for each of them.&lt;/p&gt;

&lt;p&gt;Each time you change something in the input fields or select a button, &lt;strong&gt;changeHandler&lt;/strong&gt; function will be triggered, as an argument, we take the &lt;strong&gt;event&lt;/strong&gt; object, and inside you can see that there are two variables: &lt;strong&gt;nam&lt;/strong&gt; and &lt;strong&gt;val&lt;/strong&gt; that will store information dynamically about each of the input fields. In the end, we call &lt;code&gt;this.setState&lt;/code&gt; function and pass the object as an argument. Inside of the object again we refer to &lt;strong&gt;nam&lt;/strong&gt; variable as a given key name, notice that we put &lt;strong&gt;nam&lt;/strong&gt; in the square brackets as it is the convention for the object’s keys.&lt;/p&gt;

&lt;p&gt;Now when we have all of the necessary values in our state, it is time to submit the form and add a new book object to the books array. Because of that, we will need another handler called &lt;code&gt;submitHandler&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;submitHandler = (event) =&amp;gt; {
    event.preventDefault();
    const bookNameVal = this.state.bookName;
    const bookAuthorVal = this.state.bookAuthor;
    const readVal = this.state.read;
    if (bookNameVal &amp;amp;&amp;amp; bookAuthorVal) {
      this.setState(
        (prevState) =&amp;gt; ({
          books: [
            ...prevState.books,
            {
              bookName: bookNameVal,
              bookAuthor: bookAuthorVal,
              read: readVal,
            },
          ],
        })
      );
}};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again, we use &lt;strong&gt;event&lt;/strong&gt; object in this handler, but this time for a bit different reason. Normally, when you create a form in HTML and try to submit it, the page will automatically reload. In our case, we do not want it, and in general most of the time in web development we will want to prevent this situation from happening. &lt;code&gt;event.preventDefault();&lt;/code&gt; becomes quite clear at this point. For the sake of clarity, we store key values in three variables, as you can see they will be copied directly from the state. Then in order to avoid adding books with missing title and/or author field, we wrap the rest of the code inside of &lt;strong&gt;if&lt;/strong&gt; statement. Later on, we use &lt;code&gt;this.setState&lt;/code&gt; method to add a new book to the books array. There are many ways of doing it, in my case I used &lt;strong&gt;&lt;em&gt;spread operator …&lt;/em&gt;&lt;/strong&gt; and bind a new book at the end of the array.&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing with ReactDev Tools
&lt;/h1&gt;

&lt;p&gt;It is time to make some tests before we move, and also make use of ReactDev Tools extension. Temporarily you can comment out Header and Footer components. Notice that in JSX traditional way of commenting in JavaScript will not work, instead, you can wrap the elements inside of curly brackets and then use comment symbols, just like that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import List from "./components/List";
//import Header from "./components/Header";
//import Footer from "./components/Footer";
function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      {/*&amp;lt;Header /&amp;gt; */}
      &amp;lt;List /&amp;gt;
      {/*&amp;lt;Footer /&amp;gt; */}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that go to the terminal and enter the command &lt;code&gt;npm start&lt;/code&gt;. You should see the input fields and submit button, but even after submitting the form, you will not see anything as there is no element to show our books yet, so you can use ReactDev Tools to check the component’s state and array. Each time you submit the new book, you should see it in the books array.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frcs7wbniluh3ax6w5ge6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frcs7wbniluh3ax6w5ge6.jpg" alt="checkingstate" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Table
&lt;/h1&gt;

&lt;p&gt;As our form and state are ready, handlers work and we can submit new books to the library, now we need a way to display them somehow. One of the possible ways to do it is by creating the table element, and then assign the values from &lt;code&gt;this.state.books&lt;/code&gt; array, to each new row.&lt;/p&gt;

&lt;p&gt;Right below the form in List component add this piece of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;Book Name&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Book Author&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Finished (Yes/No)&amp;lt;/th&amp;gt;
            &amp;lt;th colSpan="2"&amp;gt;Settings&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have the table columns ready now, yet there are no entries visible yet. Let’s create a reference to the books array and keep it in a variable, but this &lt;code&gt;let books = this.state.books;&lt;/code&gt; variable right after the &lt;code&gt;render()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {    
  let books = this.state.books;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is time to display books on the table by mapping the books array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;Book Name&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Book Author&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;Finished (Yes/No)&amp;lt;/th&amp;gt;
            &amp;lt;th colSpan="2"&amp;gt;Settings&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
{books.map((item, index) =&amp;gt; {
            return (
              &amp;lt;tr key={index}&amp;gt;
                &amp;lt;td&amp;gt;{item.bookName}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.bookAuthor}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.read}&amp;lt;/td&amp;gt;
                &amp;lt;td id="settings"&amp;gt;
                &amp;lt;/td&amp;gt;
              &amp;lt;/tr&amp;gt;
            );})}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you should be able to see all of the books displayed inside of the table. Does it mean that our project is finished? No.&lt;/p&gt;

&lt;h1&gt;
  
  
  What if we changed our mind about some of the books?
&lt;/h1&gt;

&lt;p&gt;Because of that reason, we will also add two buttons, in the settings column, to allow the user to change the state of each book from unfinished to finished and vice-versa, plus remove button which will enable the user to completely get rid of a given book.&lt;/p&gt;

&lt;p&gt;Inside of the last &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; element with id &lt;strong&gt;settings&lt;/strong&gt;, let’s add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;td&amp;gt;{item.bookName}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.bookAuthor}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.read}&amp;lt;/td&amp;gt;
                &amp;lt;td id="settings"&amp;gt;
                  &amp;lt;button
                    onClick​={() =&amp;gt; {
                      item.read === "Yes"
                        ? (item.read = "No")
                        : (item.read = "Yes");
                      this.forceUpdate();
                    }}
                  &amp;gt;
                    {item.read === "Yes" ? "Still reading" : "Finished"}
                  &amp;lt;/button&amp;gt;
                  &amp;lt;button
                    onClick​={() =&amp;gt; {
                      this.removeBook(index);
                    }}
                  &amp;gt;
                    Remove                  &amp;lt;/button&amp;gt;&amp;lt;/td&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the fourth column, now we have two buttons representing the book in each row. In the first one we also dynamically change the name, depending on the given object’s read property. &lt;code&gt;onClick&lt;/code&gt; methods are pretty straightforward, we will only need to add of course missing handler for &lt;code&gt;removeBook&lt;/code&gt; method. However, in the first button we have a mysterious function &lt;code&gt;this.forceUpdate();&lt;/code&gt; as you may remember, our component will be rerendered each time we call &lt;code&gt;this.setState&lt;/code&gt; method, as we do not call this method here, &lt;code&gt;this.forceUpdate();&lt;/code&gt; is a kind of workaround so we can see the book’s read status in real-time.&lt;/p&gt;

&lt;p&gt;The only missing part now is &lt;code&gt;removeBook&lt;/code&gt; handler, so we can add it now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;removeBook = (index) =&amp;gt; {
    const booksArr = [...this.state.books];
    if (booksArr) {
      this.setState(
        {
          books: booksArr.filter((book, bookIndex) =&amp;gt; {
            return bookIndex !== index;
          }),
        }
      );
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each removed booked, we will need its index, so then we can set a new state using the filter method which will omit only the book with the given index.&lt;/p&gt;

&lt;p&gt;OK, so it looks like our application only needs some style and we are ready to deploy. Not yet, as you can see the application will clear its state each time we refresh the page, which makes it useless. We will need to find a way how to store data for each user, and let them retrieve it each time they visit the website. Of course, the best option would be to create a database, a backend login etc. But this would make our app a full-stack application and make things way more complex. We can store the state for each user in two ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using local or session storage&lt;/li&gt;
&lt;li&gt;Firebase database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial, we will pick the first.&lt;/p&gt;

&lt;h1&gt;
  
  
  localStorage
&lt;/h1&gt;

&lt;p&gt;Every user on his or her own personal web browser client has access to the local storage of a given device. That is where websites store cookies for example. In our case, we can use it to store the states object in the local storage of a given user of our application. In fact, it is much easier to do then it sounds, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="noopener noreferrer"&gt;localStorage&lt;/a&gt; is a global object available in each web browser. We will need just a few extra lines of code and two more methods.&lt;/p&gt;

&lt;p&gt;Firstly, we need to add the &lt;code&gt;localStorage&lt;/code&gt; function as a second argument to the &lt;code&gt;setState&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* localStorage function        () =&amp;gt; {
          localStorage.setItem("books", JSON.stringify(this.state.books));}

        */submitHandler = (event) =&amp;gt; {
    event.preventDefault();
    const bookNameVal = this.state.bookName;
    const bookAuthorVal = this.state.bookAuthor;
    const readVal = this.state.read;
    if (bookNameVal &amp;amp;&amp;amp; bookAuthorVal) {
      this.setState(
        (prevState) =&amp;gt; ({
          books: [
            ...prevState.books,
            {
              bookName: bookNameVal,
              bookAuthor: bookAuthorVal,
              read: readVal,
            },
          ],
        }),
        () =&amp;gt; {
          localStorage.setItem("books", JSON.stringify(this.state.books));
        }
      );
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also have to add it to &lt;code&gt;removeBook&lt;/code&gt; handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;removeBook = (index) =&amp;gt; {
    const booksArr = [...this.state.books];
    if (booksArr) {
      this.setState(
        {
          books: booksArr.filter((book, bookIndex) =&amp;gt; {
            return bookIndex !== index;
          }),
        },
        () =&amp;gt; {
          localStorage.setItem("books", JSON.stringify(this.state.books));
        }
      );
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While changing the book read status, we will also have to update the localStorage so we need to add another function &lt;code&gt;this.saveLocal();&lt;/code&gt; to &lt;code&gt;onClick&lt;/code&gt; listener in each of the books.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{books.map((item, index) =&amp;gt; {
            return (
              &amp;lt;tr key={index}&amp;gt;
                &amp;lt;td&amp;gt;{item.bookName}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.bookAuthor}&amp;lt;/td&amp;gt;
                &amp;lt;td&amp;gt;{item.read}&amp;lt;/td&amp;gt;
                &amp;lt;td id="settings"&amp;gt;
                  &amp;lt;button
                    onClick​={() =&amp;gt; {
                      item.read === "Yes"
                        ? (item.read = "No")
                        : (item.read = "Yes");
                      this.saveLocal();
                      this.forceUpdate();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus the handler itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;saveLocal = () =&amp;gt; {
    localStorage.setItem("books", JSON.stringify(this.state.books));};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To display books stored in each user’s local storage, we will make use of one of the React Mounting lifecycle methods called &lt;code&gt;componentDidMount()&lt;/code&gt; which is called the last method of component’s mounting lifecycle.&lt;/p&gt;

&lt;p&gt;In other words, each time the page is loaded, this function will check if there is anything in the local storage, and call &lt;code&gt;this.setState&lt;/code&gt; method if there is something waiting in the local storage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;componentDidMount() {
    const books = localStorage.getItem("books");
    if (books) this.setState({ books: JSON.parse(books) });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Header and Footer
&lt;/h1&gt;

&lt;p&gt;To make our application look a bit better, let’s add the following code to &lt;strong&gt;Header.js&lt;/strong&gt; and &lt;strong&gt;Footer.js&lt;/strong&gt; files.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
export default class Header extends React.Component {
  render() {
    return (
      &amp;lt;h1 className="Header"&amp;gt;
        &amp;lt;img id="logoHeader" src="logo192.png" alt="React Logo"&amp;gt;&amp;lt;/img&amp;gt;
        &amp;lt;p&amp;gt;React Book Library&amp;lt;/p&amp;gt;
      &amp;lt;/h1&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
export default class Footer extends React.Component {
  render() {
    return (
      &amp;lt;footer className="Footer"&amp;gt;
        &amp;lt;p&amp;gt;
          Created with{" "}
          &amp;lt;img id="footerLogo" src="logo192.png" alt="React Logo"&amp;gt;&amp;lt;/img&amp;gt; by:
          Pawel Kowalewski
          &amp;lt;br /&amp;gt;© All rights reserved
        &amp;lt;/p&amp;gt;
      &amp;lt;/footer&amp;gt;
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  CSS
&lt;/h1&gt;

&lt;p&gt;Our application is fully functional at this moment, but it does not look very attractive, let us add some style. &lt;strong&gt;App.css&lt;/strong&gt; file should be already imported in &lt;strong&gt;App.js&lt;/strong&gt; component. I will not explain CSS in this tutorial, so feel free to change this file as you wish or just copy and paste it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html {
  background-color: antiquewhite;
}
.bookForm {
  display: grid;
  width: 400px;
  border: solid black 4px;
  border-radius: 20px;
  margin: auto auto 40px;
  padding: 20px;
  background-color: rgb(121, 121, 121);
  color: white;
  align-content: center;
}
#bookName {
  margin: 8px;
}
#bookAuthor {
  margin: 8px;
}
#read {
  margin: 8px;
}
#submit {
  margin: 8px;
  border: solid black 2px;
  border-radius: 8px;
}
table {
  width: 800px;
  margin: 0px auto;
  border: solid black 2px;
}
table,
th,
td {
  border-collapse: collapse;
}
th,
td {
  border: solid 2px black;
  padding: 4px;
  background-color: rgb(121, 121, 121);
  color: white;
}
th {
  text-align: left;
  background-color: rgb(165, 162, 162);
  color: white;
}
#settings {
  width: 200px;
}
#settings &amp;gt; * {
  margin: 4px;
  border: solid black 2px;
}
.Header {
  display: flex;
  align-items: center;
  text-align: center;
  background-color: rgb(54, 47, 46);
  color: white;
}
.Header &amp;gt; p {
  margin-left: 0px;
  margin-right: auto;
}
.Footer {
  text-align: center;
  padding: 2px 0px 2px 0px;
  margin-top: 20px;
  background-color: rgb(54, 47, 46);
  color: white;
}
#logoHeader {
  margin-right: 10px;
  margin-left: auto;
  width: 40px;
  height: 40px;
}
#footerLogo {
  width: 20px;
  height: 20px;
}
@media only screen and (max-width: 600px) {
  .bookForm,
  table {
    width: auto;
    table-layout: fixed;
  }
  td {
    word-break: break-all;
  }
}html {
  background-color: antiquewhite;
}
.bookForm {
  display: grid;
  width: 400px;
  border: solid black 4px;
  border-radius: 20px;
  margin: auto auto 40px;
  padding: 20px;
  background-color: rgb(121, 121, 121);
  color: white;
  align-content: center;
}
#bookName {
  margin: 8px;
}
#bookAuthor {
  margin: 8px;
}
#read {
  margin: 8px;
}
#submit {
  margin: 8px;
  border: solid black 2px;
  border-radius: 8px;
}
table {
  width: 800px;
  margin: 0px auto;
  border: solid black 2px;
}
table,
th,
td {
  border-collapse: collapse;
}
th,
td {
  border: solid 2px black;
  padding: 4px;
  background-color: rgb(121, 121, 121);
  color: white;
}
th {
  text-align: left;
  background-color: rgb(165, 162, 162);
  color: white;
}
#settings {
  width: 200px;
}
#settings &amp;gt; * {
  margin: 4px;
  border: solid black 2px;
}
.Header {
  display: flex;
  align-items: center;
  text-align: center;
  background-color: rgb(54, 47, 46);
  color: white;
}
.Header &amp;gt; p {
  margin-left: 0px;
  margin-right: auto;
}
.Footer {
  text-align: center;
  padding: 2px 0px 2px 0px;
  margin-top: 20px;
  background-color: rgb(54, 47, 46);
  color: white;
}
#logoHeader {
  margin-right: 10px;
  margin-left: auto;
  width: 40px;
  height: 40px;
}
#footerLogo {
  width: 20px;
  height: 20px;
}
@media only screen and (max-width: 600px) {
  .bookForm,
  table {
    width: auto;
    table-layout: fixed;
  }
  td {
    word-break: break-all;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Deployment
&lt;/h1&gt;

&lt;p&gt;As our application is finished, it is finally time for deploying it, to make it available for other users. You may also want to change the title in &lt;strong&gt;index.html&lt;/strong&gt; file and icon.&lt;/p&gt;

&lt;p&gt;Since GitHub and Netlify are very popular free services, I have decided to use them in this tutorial but you are free to deploy it anywhere you want. If you want to follow with me, I assume that you have already an account on GitHub and Netlify.&lt;/p&gt;

&lt;p&gt;Firstly go to GitHub, login and click on add new repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwvzebx4banlgs6laowm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwvzebx4banlgs6laowm2.png" alt="github" width="800" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give it some name, it can be both Public or Private and then click Create repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjg6yatipo8mide9wooar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjg6yatipo8mide9wooar.png" alt="github" width="759" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the main folder of your app and open a terminal there.&lt;/p&gt;

&lt;p&gt;Type in the following commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;copy this line from GitHub (ctrl + shift + v to paste into the terminal)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuh2n1xk9gby72nakqlly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuh2n1xk9gby72nakqlly.png" alt="github" width="766" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git status&lt;/code&gt; — to check for modified files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git add *&lt;/code&gt; to add all of the files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git status&lt;/code&gt; again to check if they are green now&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git commit -m “first”&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git branch -M main&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now your code should be uploaded to GitHub repository.&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://netlify.app/" rel="noopener noreferrer"&gt;netlify.app&lt;/a&gt; and login with your GitHub account. Once you are logged in click &lt;strong&gt;New site from Git&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6vd3m33alh67s9b9hysk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6vd3m33alh67s9b9hysk.png" alt="newsite" width="725" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, you may need to have to configure GitHub settings first. Go to GitHub and click on your profile and then settings. After that click on &lt;strong&gt;Applications&lt;/strong&gt; option from the menu and once you see Netlify click &lt;strong&gt;configure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fqeu84rjvfjv47xcamkps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fqeu84rjvfjv47xcamkps.png" alt="configure" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then scroll down until you will see Repository access, if you don’t mind you can just pick &lt;strong&gt;All repositories&lt;/strong&gt;, or select the given repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F96t1zax8epqq91lv3usw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F96t1zax8epqq91lv3usw.png" alt="repositories" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can proceed to Netlify again, when you are back at Netlify click on this option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ftepw6jzv9ykgfan6k683.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftepw6jzv9ykgfan6k683.png" alt="netlify" width="753" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, click on GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fe5q8sq2cr7sivwg8ulxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fe5q8sq2cr7sivwg8ulxn.png" alt="newsite" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the given repository, and in the last part click &lt;strong&gt;Deploy site&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fswq6cyxth0ab7rhvu56z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fswq6cyxth0ab7rhvu56z.png" alt="last" width="634" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; Your React app should be deployed and ready to use within a few minutes. Note that, you can still work on your application and make updates. Each time you commit something to the same repository, Netlify will fetch the new data and deploy the updated version automatically for you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;It was quite a long journey, I hope that you could keep on coding along with me in this tutorial and that everything was clear. However, if you have some questions, comments, suggestions etc. Please feel free to leave a comment or contact me via this website.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>npm</category>
      <category>deployment</category>
    </item>
  </channel>
</rss>
