<?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: Margai Wangara(he/him)</title>
    <description>The latest articles on DEV Community by Margai Wangara(he/him) (@margaiwangara).</description>
    <link>https://dev.to/margaiwangara</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%2F309624%2F87186844-0985-4c07-b6e5-3a46ba0769be.jpeg</url>
      <title>DEV Community: Margai Wangara(he/him)</title>
      <link>https://dev.to/margaiwangara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/margaiwangara"/>
    <language>en</language>
    <item>
      <title>Setting up macOS on a Partition of your Linux Machine</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Fri, 16 Jul 2021 16:52:48 +0000</pubDate>
      <link>https://dev.to/margaiwangara/setting-up-macos-on-a-partition-of-your-linux-machine-348b</link>
      <guid>https://dev.to/margaiwangara/setting-up-macos-on-a-partition-of-your-linux-machine-348b</guid>
      <description>&lt;p&gt;So, woke up this morning, checked my LinkedIn account, and, the most amazing thing happened. &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:6818161112639406080"&gt;Someone had posted a solution to a problem&lt;/a&gt; I have been having for a long time, and it was awesome. Being a once in a while mobile apps developer, I always looked for ways to be able to test my hybrid React Native apps on an iPhone device to no avail. Basically, unless you have a macOS, or an iPhone, good luck testing your app. This always led to issues, like the well-known Internet Explorer explorer issues, whereby your app looks great on Chrome and Firefox but when you it check out Internet Explorer it looks like the app went to hell and came back.&lt;/p&gt;

&lt;p&gt;Based on the &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:6818161112639406080/"&gt;post&lt;/a&gt;, one can use &lt;a href="https://github.com/popey/sosumi-snap"&gt;sosumi&lt;/a&gt; to run macOS on their Linux machines. So, I embarked on a journey to try and figure out how I can pull this off. I then came across &lt;a href="https://www.linuxuprising.com/2020/03/how-to-install-macos-in-virtual-machine.html"&gt;this article&lt;/a&gt; by &lt;a href="https://www.blogger.com/profile/03026963810377267607"&gt;Logix&lt;/a&gt; on the &lt;a href="https://www.linuxuprising.com/"&gt;Linux Uprising&lt;/a&gt; blog, which provides an awesome step by step guide on getting the stuff running on one's machine. I definitely suggest a read. While trying out the steps, I hit a snag, kind of a big one, my machine did not have enough space for a complete installation. I however had different partitions with enough space to accommodate the installation. The problem though, is that I didn't know how to install it in a different partition. Then came a comment by Hikmat E Ustad, providing an alternative way to install from a YouTube video he created. The video can be found &lt;a href="https://www.youtube.com/watch?v=c30RLycIpVY"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The video did not provide a solution to my problem but after contacting him(basically wrote a comment), he directed me to a &lt;a href="https://superuser.com/questions/618484/how-can-i-use-a-separate-partition-to-store-the-vm-images-in-kvm"&gt;link&lt;/a&gt; which provided me a with a starting point. That is when the fun started.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Virtual Drive
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;To create a virtual drive, search and open &lt;code&gt;virt-manager&lt;/code&gt; on your Linux OS, I use Ubuntu so it was already installed.&lt;/li&gt;
&lt;li&gt;We then add the disk to the KVM Storage pool via virt-manager. To create a new VM, on the menu bar, click on edit, then choose "Connection Details". &lt;/li&gt;
&lt;li&gt;Open the "Storage" tab then click the green + button on the far bottom left. On the popup window, write the &lt;code&gt;Name&lt;/code&gt;, then on the &lt;code&gt;Type&lt;/code&gt; dropdown choose &lt;code&gt;dir: Filesystem Directory&lt;/code&gt;, on the &lt;code&gt;Target Path&lt;/code&gt;, click the &lt;code&gt;Browse&lt;/code&gt; button on the right. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;File Explorer&lt;/code&gt; will popup and you have to select a location as your target. This is where we select the partition we want. &lt;/li&gt;
&lt;li&gt;&lt;p&gt;To select a partition, click on &lt;code&gt;+ Other Locations&lt;/code&gt; on the left sidebar of the &lt;code&gt;file explorer&lt;/code&gt; window. You will then see the list of all your partitions, normally with a &lt;code&gt;/dev/&amp;lt;some name&amp;gt;&lt;/code&gt; on the right. Mine was &lt;code&gt;/dev/sdb2&lt;/code&gt;. Click on the partition to mount it then you can create a folder inside and set the folder as your &lt;code&gt;target path&lt;/code&gt;. You can then click the green button on the top-right of the window. The most important part is getting the path to the partition, this can be found once you click the green button at the top right, and on the next popup window, click finish.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you are done creating the pool above, the "Connection Details" window will be open and from the left sidebar choose the name of the pool you created. Details of that pool will be displayed on the right. Keep this window open and follow the instructions below to install macOS on your machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Installing macOS
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="https://github.com/kholia/OSX-KVM#readme"&gt;this repo&lt;/a&gt; and follow the instructions step by step up to the part below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 mac_hdd_ng.img 128G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above creates a virtual hdd image where macOS will be installed. We have to change the location to the pool target we created above. Go back to point 6. and copy &lt;code&gt;Location&lt;/code&gt;, it is usually something like this &lt;code&gt;/media/&amp;lt;username&amp;gt;/01D6CA5DC685C8B0/&amp;lt;folder you created&amp;gt;&lt;/code&gt;. Replace the above command with:&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="c"&gt;# PS: 128G is the size of the virtual drive in Gigabytes that will be created&lt;/span&gt;
qemu-img create &lt;span class="nt"&gt;-f&lt;/span&gt; qcow2 /media/&amp;lt;username&amp;gt;/01D6CA5DC685C8B0/&amp;lt;folder you created&amp;gt;/mac_hdd_ng.img 128G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command creates a &lt;code&gt;128GB&lt;/code&gt; virtual hdd in the location you specified, in this situation, the partition you added to the pool. After running the command above, since we changed the location of our virtual hdd, we also need to set this location in our script which will be run immediately after this command. So before running the script, we need to open it and change the location. To open the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano ./OpenCore-Boot.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens the script in the terminal, we can then create a new variable, find the line with the variable &lt;code&gt;REPO_PATH="."&lt;/code&gt; and on the next line add this variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NVM_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/media/&amp;lt;username&amp;gt;/01D6CA5DC685C8B0/&amp;lt;folder you created&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then find this line:&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="nt"&gt;-drive&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MacHDD,if&lt;span class="o"&gt;=&lt;/span&gt;none,file&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPO_PATH&lt;/span&gt;&lt;span class="s2"&gt;/mac_hdd_ng.img"&lt;/span&gt;,format&lt;span class="o"&gt;=&lt;/span&gt;qcow2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and replace &lt;code&gt;$REPO_PATH&lt;/code&gt; with &lt;code&gt;$NVM_PATH&lt;/code&gt;, then save and close by pressing &lt;code&gt;ctrl+X&lt;/code&gt; then &lt;code&gt;Enter&lt;/code&gt;. You can then run the script by typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./OpenCore-Boot.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this point, you can read &lt;a href="https://www.linuxuprising.com/2020/03/how-to-install-macos-in-virtual-machine.html"&gt;this article&lt;/a&gt; or watch &lt;a href="https://www.youtube.com/watch?v=c30RLycIpVY"&gt;this video&lt;/a&gt; to complete the installation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This might not necessarily be the best approach but it it the approach that worked for me. In case I made any mistake, please feel free to constructively criticize in the comments.&lt;/p&gt;

</description>
      <category>linux</category>
    </item>
    <item>
      <title>How to Toggle Input Field Values With React Hooks</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Fri, 11 Dec 2020 18:08:53 +0000</pubDate>
      <link>https://dev.to/margaiwangara/hide-or-show-input-field-value-with-react-hooks-36de</link>
      <guid>https://dev.to/margaiwangara/hide-or-show-input-field-value-with-react-hooks-36de</guid>
      <description>&lt;p&gt;I have been coding in React for some time now(a while, like a long while) and throughout this period, I have come across some awesome stuff. However, for some reason, every time I created an authentication form, I didn't really feel the need to provide the user with the need to view their password while or after their input. Recently, I decided to integrate that option(feature I guess) and this is how I did it(more or less). I'll be using React Hooks, because, well, they're awesome and I kind of don't like writing classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;The main concept behind pulling this off is one word actually, &lt;strong&gt;toggling&lt;/strong&gt;. Basically, what we want to do is this, when the user clicks on a certain icon/field/element, we change the state accordingly such that if the input type is &lt;strong&gt;password&lt;/strong&gt;, we show &lt;strong&gt;text&lt;/strong&gt; and vice versa. To achieve this, we initialize two state variables, &lt;strong&gt;&lt;em&gt;inputValue&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;isInputVisible&lt;/em&gt;&lt;/strong&gt;. We then check the state(pun intended) of these variables and display based on that.  Don't forget the state-changing functions or &lt;em&gt;state-setters&lt;/em&gt; if you will. We name them &lt;strong&gt;&lt;em&gt;setInputValue&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;setIsInputVisible&lt;/em&gt;&lt;/strong&gt; respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/eye-regular.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;hide&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./assets/eye-slash-regular.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setInputValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// boilerplate React stuff&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsInputVisible&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"passwordField"&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setInputValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;
              &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;eye&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setIsInputVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
                    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;hide&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password-toggle"&lt;/span&gt;
                    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100vh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;form&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;80%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;div&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;solid 2px var(--secondary)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;15px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ddd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;eye&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;25px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;absolute&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;top&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="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pointer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;## Explaining the code&lt;/p&gt;

&lt;p&gt;Just to get it out of the way, I added some in-line styling to, you know, spice things up a little bit. &lt;/p&gt;

&lt;p&gt;The magic is within the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tags. Inside the &lt;code&gt;input&lt;/code&gt; tag, we have some stuff going on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
     &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"passwordField"&lt;/span&gt;
     &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setInputValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;
     &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the &lt;code&gt;input&lt;/code&gt; type, we check if &lt;code&gt;isInputVisible&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, if &lt;code&gt;true&lt;/code&gt;, it means the user would like to view the password entered, we therefore change the type to &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, we set the type to &lt;code&gt;password&lt;/code&gt;, which is basically just a bunch of dots.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;value&lt;/code&gt; attribute is bound to state, which is modified by the next line &lt;code&gt;onChange&lt;/code&gt; which modifies the state based on any change to the input element, in this situation, user input is the change. &lt;code&gt;e.target&lt;/code&gt; refers to the input element, we then get the target's &lt;code&gt;value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We then have a &lt;code&gt;span&lt;/code&gt; element, which just acts as the container to the &lt;code&gt;image&lt;/code&gt; tag which contains the eye icon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;eye&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setIsInputVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isInputVisible&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;hide&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password-toggle"&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the &lt;code&gt;img&lt;/code&gt; tag, we change the source &lt;code&gt;src&lt;/code&gt; based on the state of the &lt;code&gt;isInputVisible&lt;/code&gt; variable. If the &lt;code&gt;isInputVariable&lt;/code&gt; is true, we show the &lt;code&gt;hide&lt;/code&gt;&lt;strong&gt;&lt;em&gt;(eye with a slash)&lt;/em&gt;&lt;/strong&gt; icon, else, we show the &lt;code&gt;view&lt;/code&gt;&lt;strong&gt;&lt;em&gt;(eye)&lt;/em&gt;&lt;/strong&gt; icon. &lt;/p&gt;

&lt;p&gt;This variable's state is modified with an &lt;code&gt;onClick&lt;/code&gt; event to the &lt;code&gt;span&lt;/code&gt;, parent of the &lt;code&gt;img&lt;/code&gt; tag. &lt;code&gt;onClick&lt;/code&gt;, the &lt;code&gt;setIsInputVisible&lt;/code&gt; function returns the negation of the &lt;code&gt;isInputVisible&lt;/code&gt; variable meaning if &lt;code&gt;isInputVisible&lt;/code&gt; is true, it returns &lt;code&gt;false&lt;/code&gt; and vice versa.&lt;/p&gt;

&lt;p&gt;I have attached a link to view the entire code and its result, &lt;strong&gt;two&lt;/strong&gt; of the &lt;strong&gt;MISSING&lt;/strong&gt; imports can be found in the attached link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/muddy-smoke-shh2n?file=/src/App.js"&gt;https://codesandbox.io/s/muddy-smoke-shh2n?file=/src/App.js&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Load Static CSS and JS Files in Next.js</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Sat, 21 Nov 2020 21:48:21 +0000</pubDate>
      <link>https://dev.to/margaiwangara/how-to-load-static-css-and-js-files-in-next-js-393m</link>
      <guid>https://dev.to/margaiwangara/how-to-load-static-css-and-js-files-in-next-js-393m</guid>
      <description>&lt;p&gt;Recently I was working on a project that required conversion from a static HTML/CSS/JS theme to a Next.js application. I had done some hardcore React before so making a switch to Next.js wasn't that hard, it was pretty simple, to be honest, and I also wanted to benefit from the API routes availability and SEO advantages of using Next.js due to its server-side rendering capabilities. One of the issues I didn't take into consideration was the server-side rendering effect on normal &lt;code&gt;js&lt;/code&gt; files execution. This ended up taking my entire week as I tried to figure out a way to integrate &lt;code&gt;js&lt;/code&gt; files without painting my Chrome console red.&lt;/p&gt;

&lt;p&gt;For me, this was a pretty straightforward situation, all I had to do was to import the &lt;code&gt;css&lt;/code&gt; and &lt;code&gt;js&lt;/code&gt; files into &lt;code&gt;index.html&lt;/code&gt; file, but wait, Next.js doesn't have an &lt;code&gt;index.html&lt;/code&gt; file. This was my first issue. Fortunately, after a little bit of research in the &lt;a href="https://nextjs.org"&gt;Next.js documentation&lt;/a&gt;, I figured it out(kind of). So, to import &lt;code&gt;js&lt;/code&gt; and &lt;code&gt;css&lt;/code&gt; files, it's pretty easy. In the &lt;code&gt;pages&lt;/code&gt; directory, create a &lt;code&gt;_document.js&lt;/code&gt; file and add the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To call the &lt;code&gt;css&lt;/code&gt; and &lt;code&gt;js&lt;/code&gt; as above, the files need to be available in the &lt;code&gt;public&lt;/code&gt; folder on the root of the project.&lt;/p&gt;

&lt;p&gt;The above code works as expected under normal circumstances. &lt;code&gt;CSS&lt;/code&gt; files are rendered and work as expected, however, when using &lt;code&gt;JS&lt;/code&gt;, since some properties such as &lt;code&gt;window&lt;/code&gt;  are only available on the client-side, it throws errors. I had this problem, particularly when trying to use &lt;code&gt;owl.min.js&lt;/code&gt; and &lt;code&gt;wow.min.js&lt;/code&gt; files for slideshows because they utilize &lt;code&gt;window&lt;/code&gt;. The most common error I faced was the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Warning: Extra attributes from the server: style &lt;span class="k"&gt;in &lt;/span&gt;nav &lt;span class="o"&gt;(&lt;/span&gt;at DefaultNavbar.tsx:38&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a bit of research, I got a variety of solutions, which were really awesome and helpful, like checking if &lt;code&gt;window&lt;/code&gt; exists inside the lifecycle method &lt;code&gt;componentDidMount&lt;/code&gt; and then load the library, while this was helpful, I didn't know how I could load the static &lt;code&gt;js&lt;/code&gt; files. So, after struggling for almost a week, I finally managed to load the &lt;code&gt;js&lt;/code&gt; files without any errors as follows:&lt;/p&gt;

&lt;p&gt;In the code above, while loading a &lt;code&gt;js&lt;/code&gt; file, add the &lt;code&gt;async={true}&lt;/code&gt; property which loads the &lt;code&gt;script&lt;/code&gt; file when ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyDocument&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To learn more about &lt;strong&gt;Next.js&lt;/strong&gt; &lt;code&gt;_document.js&lt;/code&gt;, you can check out the documentation &lt;a href="https://nextjs.org/docs/advanced-features/custom-document"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How To: Set Up Remote Redis on DigitalOcean And Use it on your Local Application</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Fri, 13 Nov 2020 18:00:47 +0000</pubDate>
      <link>https://dev.to/margaiwangara/how-to-set-up-remote-redis-on-digitalocean-and-use-it-on-your-local-application-2a74</link>
      <guid>https://dev.to/margaiwangara/how-to-set-up-remote-redis-on-digitalocean-and-use-it-on-your-local-application-2a74</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This configuration can be applied on any server running Ubuntu.&lt;/p&gt;

&lt;p&gt;I was recently redesigning an &lt;a href="https://sinema.margaiwangara.me"&gt;app&lt;/a&gt; I developed a while ago with Node.js, React and GraphQL because, apparently, its design was "too stretched" and "didn't look so good" (I low-key agree). So, I dove into dribbble to look for an awesome design I could borrow. &lt;strong&gt;Sidebar: I really appreciate all the awesome open source designs created by the super talented UI/UX designers out there&lt;/strong&gt;. After a bit of digging, I found a &lt;a href="https://dribbble.com/shots/2759291-Movie-Application-UI"&gt;design&lt;/a&gt; by &lt;a href="https://dribbble.com/riks"&gt;Ricardo Salazar&lt;/a&gt;. It was simple and easily implementable. With a few color changes, I managed to recreate the design and implement my React front-end using data from my GraphQL API.&lt;br&gt;
During this process, I realized that to get the data I wanted, I needed to make a lot of requests to the external API I was using. Despite the API being free and without rate limits, I felt like I was abusing the resources that were provided. To solve this problem, I thought about using a database to store the data then performing the requests from my own server but I realized this would be highly inefficient due to the dynamic nature of the data from the external API. So, I decided to look at other options, that is when I remembered &lt;strong&gt;Redis&lt;/strong&gt;.&lt;br&gt;
I had done some storage with Redis before to perform authentication and session management with Express.js. After a bit of research, I came to the conclusion that redis was the way to go. Another issue was that, since I was using shared hosting with a cpanel, I could not install and use redis on my host. I had to find a way. &lt;br&gt;
Then comes &lt;a href="https://education.github.com/pack"&gt;Github Student Pack&lt;/a&gt;. Github provides a bunch of resources to help students use services like DigitalOcean by providing coupons and other options. I highly recommend if for students getting into or already developing awesome stuff. I was able to get a coupon for $50 on DigitalOcean and set up my droplet. I also did the initial set-up which has been provided in detail in &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04"&gt;this article&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Redis on a DigitalOcean droplet
&lt;/h2&gt;

&lt;p&gt;To install redis, 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;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;redis-server

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

&lt;/div&gt;



&lt;p&gt;This will download and install Redis and its dependencies. We will then make some modifications to the Redis config file to add authentication and secure our Redis database.&lt;/p&gt;

&lt;p&gt;Open the config file by writing this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/redis/redis.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the config file, we will locate and modify the following areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;supervised&lt;/li&gt;
&lt;li&gt;security &lt;/li&gt;
&lt;li&gt;bind&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting supervised to systemd
&lt;/h3&gt;

&lt;p&gt;Locate the line which contains &lt;code&gt;supervised&lt;/code&gt; option and change it to &lt;code&gt;systemd&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# If you run Redis from upstart or systemd, Redis can interact with your&lt;/span&gt;
&lt;span class="c"&gt;# supervision tree. Options:&lt;/span&gt;
&lt;span class="c"&gt;#   supervised no      - no supervision interaction&lt;/span&gt;
&lt;span class="c"&gt;#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode&lt;/span&gt;
&lt;span class="c"&gt;#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET&lt;/span&gt;
&lt;span class="c"&gt;#   supervised auto    - detect upstart or systemd method based on&lt;/span&gt;
&lt;span class="c"&gt;#                        UPSTART_JOB or NOTIFY_SOCKET environment variables&lt;/span&gt;
&lt;span class="c"&gt;# Note: these supervision methods only signal "process is ready."&lt;/span&gt;
&lt;span class="c"&gt;#       They do not enable continuous liveness pings back to your supervisor.&lt;/span&gt;
supervised systemd

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Modifying Password
&lt;/h3&gt;

&lt;p&gt;Since we need to set a secure password for the Redis, we will need to use openssl to generate a strong password. To generate a password, open a new tab on the terminal and run the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;openssl rand 60 | openssl &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above generates a strong password made up of random characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The security section of the Redis config file provides us with an area to specify the password of our Redis server. To set the password, in the config file, locate the security section and uncomment the &lt;code&gt;#requirepass foobared&lt;/code&gt; then change the password from &lt;code&gt;foobared&lt;/code&gt; to the password we generated above.&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="c"&gt;#/etc/redis/redis.conf&lt;/span&gt;

&lt;span class="c"&gt;################################## SECURITY ###################################&lt;/span&gt;

&lt;span class="c"&gt;# Require clients to issue AUTH &amp;lt;PASSWORD&amp;gt; before processing any other&lt;/span&gt;
&lt;span class="c"&gt;# commands.  This might be useful in environments in which you do not trust&lt;/span&gt;
&lt;span class="c"&gt;# others with access to the host running redis-server.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# This should stay commented out for backward compatibility and because most&lt;/span&gt;
&lt;span class="c"&gt;# people do not need auth (e.g. they run their own servers).&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Warning: since Redis is pretty fast an outside user can try up to&lt;/span&gt;
&lt;span class="c"&gt;# 150k passwords per second against a good box. This means that you should&lt;/span&gt;
&lt;span class="c"&gt;# use a very strong password otherwise it will be very easy to break.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
 requirepass vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Modifying bind
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;To make our redis database accessible, we will have to bind it to an external IP address which is not very secure. In this tutorial, we will bind it to 0.0.0.0 which makes it available everywhere&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the config file we opened above, locate the line below and make sure it is uncommented(by removing the &lt;code&gt;#&lt;/code&gt; at the beginning if it exists) and change the IP address to &lt;code&gt;0.0.0.0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#/etc/redis/redis.conf&lt;/span&gt;

&lt;span class="nb"&gt;bind &lt;/span&gt;127.0.0.1 ::1 &lt;span class="c"&gt;# change this line to bind 0.0.0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After modifying the config file, press &lt;code&gt;ctrl+x&lt;/code&gt; on &lt;code&gt;Windows or Linux&lt;/code&gt; or &lt;code&gt;command+x&lt;/code&gt; on &lt;code&gt;Mac&lt;/code&gt; then press &lt;code&gt;y&lt;/code&gt; then &lt;code&gt;enter&lt;/code&gt; to save the file then restart Redis by running the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart redis.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then test our Redis. To test the password, access the Redis command line by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;redis-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then write a series of commands to check if the Redis password works. At first, we try to set a key and value before authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.0:6379&amp;gt; set hello "Hello World"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces an error because we need to set the password:&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="c"&gt;#Output&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt; NOAUTH Authentication Required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then specify the password we added above in the config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1:6379&amp;gt; auth &amp;lt;redis-password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redis will produce a message, &lt;code&gt;OK&lt;/code&gt;, to inform you that the password has been accepted. We can then try to store the key and value as we tried above.&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="c"&gt;# setting value&lt;/span&gt;
127.0.0.1:6379&amp;gt; &lt;span class="nb"&gt;set &lt;/span&gt;hello &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="c"&gt;#getting value&lt;/span&gt;
127.0.0.1:6379&amp;gt; get hello

&lt;span class="c"&gt;#output "Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then exit the Redis client with the command &lt;code&gt;quit&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Remote Redis on your local Express Application
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you are using a firewall on your DigitalOcean server, you need to enable access for port &lt;code&gt;6379&lt;/code&gt; in order to use it on your local application. To enable the port for external access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ufw allow 6379/tcp

&lt;span class="c"&gt;#checking if port has been added to ufw list&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then initialize a simple express app by installing a few packages.&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="c"&gt;# Initialize Express app&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Installing packages - Express and Redis&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file on the root of your project then write the code below:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// These should be environment variables, use a package like dotenv to store these data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REDIS_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6379&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REDIS_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;DO_IP_ADDRESS&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// This is the IP address of your DigitalOcean droplet&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REDIS_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vWHK8OXixGiUU1kimf+Bo4WM+vu8t7Bpdk7VZHvtBc7caNeCDBK1Etazy/1Hho+/Uou4Mr1/gXk0hdNM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// This is the password we created above for our Redis database.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redisClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;REDIS_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;REDIS_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;REDIS_PASSWORD&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Log errors in case of Redis connection failure&lt;/span&gt;
&lt;span class="nx"&gt;redisClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Redis Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Set Express server PORT&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`App running in on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, you can use the remote Redis to store and access your data. &lt;/p&gt;

&lt;p&gt;To get more details on securely configuring Redis on your DigitalOcean server, you can check out the link below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04"&gt;How To Install and Secure Redis on Ubuntu&lt;/a&gt;&lt;/p&gt;

</description>
      <category>redis</category>
      <category>node</category>
    </item>
    <item>
      <title>Back To Basics: Git</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Thu, 12 Mar 2020 11:27:45 +0000</pubDate>
      <link>https://dev.to/margaiwangara/back-to-basics-git-35fe</link>
      <guid>https://dev.to/margaiwangara/back-to-basics-git-35fe</guid>
      <description>&lt;p&gt;Personally, I believe that aspiring developers should learn git/version control before engaging into any kind of programming. Git is extremely important in programming. I remember when I was starting out, I had no idea what version control was. Infact, I only learnt about git about two years into my programming career (courtesy of &lt;a href="https://www.youtube.com/watch?v=SWYqp7iY_Tc"&gt;Traversy Media's git course&lt;/a&gt;) and it was awesome.&lt;br&gt;
Learning the basics of git is simple since to start out, one needs to only learn three commands.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialze a project as a git repository&lt;/li&gt;
&lt;li&gt;Add files&lt;/li&gt;
&lt;li&gt;Commit added files&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Installation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Download git from &lt;a href="%5Bhttps://git-scm.com/downloads%5D(https://git-scm.com/downloads)"&gt;here&lt;/a&gt;  and install on your computer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once git is installed, open the command line and type &lt;code&gt;git&lt;/code&gt; then press &lt;code&gt;enter&lt;/code&gt;. A long list of commands should be displayed.&lt;/p&gt;

&lt;p&gt;Lets create a project and name it &lt;code&gt;hello_world&lt;/code&gt;. Open the folder and git bash directly into it by right clicking and choosing &lt;code&gt;Git bash here&lt;/code&gt; option from the dropdown list. Once the terminal is opened, type &lt;code&gt;git init&lt;/code&gt; to initialize the folder as a git repository.&lt;/p&gt;

&lt;p&gt;We can then add a file into the folder by typing &lt;code&gt;touch index.html&lt;/code&gt;. This creates a html file. Open the html inside any text editor and add the following code (for testing purposes).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
    &lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
            Hello World from Git!
        &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adding files to git
&lt;/h4&gt;

&lt;p&gt;To add changed files to git,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To add a single file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    git add index.html

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To add all files
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    git add &lt;span class="nb"&gt;.&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Commiting files
&lt;/h4&gt;

&lt;p&gt;Commiting files provides a point of reference incase you want to revert your code to a certain point&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'Initial Commit'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-m&lt;/code&gt; flag lets you add a message with your commit so as to understand what changes you made or files you added at that particular commit.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ignoring files and folders
&lt;/h4&gt;

&lt;p&gt;Git provides you with the ability to ignore files and folders that exist in your working folder which you don't want to add to your git repository. To ignore files and folder create a &lt;code&gt;.gitignore&lt;/code&gt; file and add the name of the file or folder&lt;/p&gt;

&lt;p&gt;In your terminal create a file and folder as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a file
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    &lt;span class="nb"&gt;touch &lt;/span&gt;ignorefile.txt

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creating a folder
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    &lt;span class="nb"&gt;mkdir &lt;/span&gt;ignorefolder

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a gitignore file to ignore the files and folders
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    &lt;span class="nb"&gt;touch&lt;/span&gt; .gitignore

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

&lt;/div&gt;



&lt;p&gt;You can open the gitignore file with your text editor or edit directly from the terminal. To edit directly from the terminal,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    nano .gitignore

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

&lt;/div&gt;



&lt;p&gt;The command above opens the gitignore file in terminal, once the file is opened press &lt;code&gt;i&lt;/code&gt; then write,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
    ignorefile.txt
    ignorefolder/

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

&lt;/div&gt;



&lt;p&gt;Then press &lt;code&gt;CTRL/Command + X&lt;/code&gt; to exit. Then press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The file and folder will be ignored anytime the &lt;code&gt;git add .&lt;/code&gt; command is executed.&lt;/p&gt;

&lt;p&gt;Incase of any error, please feel free to comment or constructively criticize.&lt;/p&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Back To Basics: CRUD Operations with SQL</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Tue, 10 Mar 2020 19:46:34 +0000</pubDate>
      <link>https://dev.to/margaiwangara/back-to-basics-crud-operations-with-sql-5343</link>
      <guid>https://dev.to/margaiwangara/back-to-basics-crud-operations-with-sql-5343</guid>
      <description>&lt;p&gt;I was recently going through my old projects trying to refactor them for inclusion into my &lt;a href="https://margaiwangara.me"&gt;portfolio website&lt;/a&gt; when I came across one of my first-ever full-stack projects. Back then, I mostly used structural PHP as my main back-end programming language. Being new to programming, I was excited, I mean, why not, programming is so cool.  One of the best moments of my life was when I had my first programming 'aha' moment. It was amazing. Since then, I have created lots of projects, some finished, others unfinished, all with one goal in mind, building something.&lt;/p&gt;

&lt;p&gt;Since I mainly used PHP (structural) for back-end, most of the time I wrote raw SQL queries, from database connections to creating tables and to be honest, it was quite refreshing. I gained a bunch of experience in SQL until I decided to shift to Node.js and the MERN stack for web development. &lt;/p&gt;

&lt;p&gt;With the introduction of packages like Eloquent, it is easier to perform &lt;strong&gt;CRUD&lt;/strong&gt; operation on a table without having any idea what happens under the hood. I decided to write this article to share my knowledge on the matter and in the process also remind myself how it actually works&lt;/p&gt;

&lt;p&gt;For compatibility, I will use &lt;a href="http://sqlfiddle.com/"&gt;sqlfiddle&lt;/a&gt; to write the queries. Feel free to use any SQL editor. Possible options include &lt;a href="https://apachefriends.org"&gt;&lt;strong&gt;XAMPP&lt;/strong&gt;&lt;/a&gt; which comes with MySQL, Apache and PHP, VSCode's SQLite extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
    &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTO_INCREMENT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;surname&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&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 table called users if it does not exist and then adds columns as specified&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;INT&lt;/strong&gt; - Accepts whole numbers only.&lt;br&gt;
&lt;strong&gt;VARCHAR&lt;/strong&gt; - Accepts strings with length specified in brackets&lt;br&gt;
&lt;strong&gt;TEXT&lt;/strong&gt; - Accepts long string such as descriptions&lt;br&gt;
&lt;strong&gt;TIMESTAMP&lt;/strong&gt; - Accepts timestamps&lt;/p&gt;

&lt;h3&gt;
  
  
  Attributes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PRIMARY_KEY&lt;/strong&gt; - Sets column as primary key&lt;br&gt;
&lt;strong&gt;AUTO_INCREMENT&lt;/strong&gt; - Increases column value by specified increment value, 1 by default&lt;br&gt;
&lt;strong&gt;UNIQUE&lt;/strong&gt; - Column stores unique values, like email, values that are not the same&lt;br&gt;
&lt;strong&gt;NOT NULL&lt;/strong&gt; - Required values&lt;br&gt;
&lt;strong&gt;DEFAULT&lt;/strong&gt; - Default column value such as &lt;strong&gt;CURRENT_TIMESTAMP&lt;/strong&gt; -  For the current date and time&lt;/p&gt;

&lt;h2&gt;
  
  
  C - Adding data to users table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
    &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Doe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'johndoe@app.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'JohnDoe1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'The name is Doe. John Doe'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Since we are using &lt;strong&gt;auto_increment&lt;/strong&gt;, &lt;strong&gt;id&lt;/strong&gt; is automatically added and incremented on addition of a new row, &lt;strong&gt;created_at&lt;/strong&gt; and &lt;strong&gt;updated_at&lt;/strong&gt; fields are also automatically filled because we set the default as &lt;strong&gt;current_timestamp&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  R - Read data from users table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="c1"&gt;-- Select everything from users table&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select some from users table&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select from users table where&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'johndoe@app.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select from users table where ... and ...&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'John'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;surname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Doe'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select from users table where ... or ...&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'John'&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;surname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Doe'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Select has a variety of options. Where is used to select and filter based on specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  U - Update existing data in users table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="c1"&gt;-- Update name to jane doe using email[unique]&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Jane'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'johndoe@app.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Update email to janedoe using id[assume = 1]&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'janedoe@app.com'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  D - Delete data from users table
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
&lt;span class="c1"&gt;-- Deleting entire table data[beware]&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Deleting certain row data&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'janedoe@app.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;When writing the &lt;code&gt;delete&lt;/code&gt; query be careful not to delete all data from the table by using &lt;code&gt;where&lt;/code&gt;. I remember messing up a lot when I was starting out.&lt;/p&gt;

&lt;p&gt;Incase I wrote anything wrongly, feel free to constructively criticize in the comments section.&lt;/p&gt;

</description>
      <category>sql</category>
    </item>
    <item>
      <title>Simple GraphQL API with Express and MongoDB</title>
      <dc:creator>Margai Wangara(he/him)</dc:creator>
      <pubDate>Sun, 12 Jan 2020 19:49:38 +0000</pubDate>
      <link>https://dev.to/margaiwangara/simple-graphql-api-with-express-and-mongodb-2f2b</link>
      <guid>https://dev.to/margaiwangara/simple-graphql-api-with-express-and-mongodb-2f2b</guid>
      <description>&lt;p&gt;After learning GraphQL and building my first ever GraphQL API (check out &lt;a href="https://twentyfourseven.margaiwangara.me"&gt;https://twentyfourseven.margaiwangara.me&lt;/a&gt; for react app) by consuming the TMDB REST API using Express and creating an interface using React.js, I decided to challenge myself to see if I could utilize the same concepts and combine it with my knowledge of MongoDB and Express to create a database and perform a single CRUD operation. Finally, this is what I was able to achieve in a few minutes.&lt;/p&gt;

&lt;p&gt;To run the app and try it out, check out the index file in my 'models' folder and add the MongoDB connection string.&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@margaiwangara/ForcefulAuthenticEngineer?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


</description>
      <category>replit</category>
      <category>node</category>
      <category>express</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
