<?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: Team ORNIO</title>
    <description>The latest articles on DEV Community by Team ORNIO (@ornio).</description>
    <link>https://dev.to/ornio</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%2Forganization%2Fprofile_image%2F2465%2F0a90a52e-f20e-4ca2-b0a4-b42c9b915f8b.png</url>
      <title>DEV Community: Team ORNIO</title>
      <link>https://dev.to/ornio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ornio"/>
    <language>en</language>
    <item>
      <title>Create custom CRA (create-react-app) template with tailwindcss, twin.macro and goober</title>
      <dc:creator>Redžep Murati</dc:creator>
      <pubDate>Wed, 14 Jul 2021 13:14:48 +0000</pubDate>
      <link>https://dev.to/ornio/create-custom-cra-create-react-app-template-with-tailwindcss-twin-macro-and-goober-5oe</link>
      <guid>https://dev.to/ornio/create-custom-cra-create-react-app-template-with-tailwindcss-twin-macro-and-goober-5oe</guid>
      <description>&lt;p&gt;Have you ever felt the pain of starting a new React project?&lt;/p&gt;

&lt;p&gt;Create the app via CRA, add your tools, add you common utilities, hooks, configs, structure, linters, etcetera etcetera.&lt;/p&gt;

&lt;p&gt;It's frustrating having to start from ground zero each and every time. 😠&lt;/p&gt;

&lt;p&gt;If only there was a better way?!&lt;/p&gt;

&lt;p&gt;Being a developer I'm plagued with the same disease as everyone else. I hate repetitive tasks and if I can automate something, you can bet I will.&lt;/p&gt;

&lt;p&gt;In this step by step guide we are going to explore how we can rewire React's CRA template to create a custom template bundled with our unique setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a CRA (create-react-app)?
&lt;/h3&gt;

&lt;p&gt;Create React App is an official way to create single-page React applications. &lt;br&gt;
Basically it is a zero-config toolchain that takes away all the hustle with hot reloading, live server and webpack configuration. It’s a one size fits all solution with only the bare minimum to get you up and running as fast as possible.&lt;/p&gt;

&lt;p&gt;By default React team (shout out for an amazing work ❤️) has created two templates for us, a basic javascript template &lt;a href="https://github.com/facebook/create-react-app/tree/master/packages/cra-template" rel="noopener noreferrer"&gt;cra-template&lt;/a&gt; and a basic typescript template &lt;a href="https://github.com/facebook/create-react-app/tree/master/packages/cra-template-typescript" rel="noopener noreferrer"&gt;crate-template-typescript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the purpose of this guide I will be using a typescript template, but you can choose whatever suits you the most.&lt;/p&gt;

&lt;p&gt;The only real difference between the two is typescript.&lt;/p&gt;

&lt;p&gt;We will start by taking a look at CRA template provided by the React team.&lt;br&gt;
It contains a &lt;strong&gt;template&lt;/strong&gt; folder and two files &lt;strong&gt;template.json&lt;/strong&gt; and &lt;strong&gt;package.json&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Template folder shares the same structure as a normal react app. &lt;br&gt;
It has a &lt;strong&gt;public&lt;/strong&gt; folder with a basic logo, manifest and robots files as well as an index.html file and a src folder where all your source code is.&lt;/p&gt;

&lt;p&gt;As far as files go template.json is a file that represents how our package will look (actual package.json when app is created) it contains all our dependencies and scripts.&lt;/p&gt;

&lt;p&gt;On the other hand, although a bit counter intuitive for beginners, the package.json file is just a representation of template information not app information. It contains template name, version and template files.&lt;/p&gt;

&lt;p&gt;Now that we have covered the basics we can start building our own template.&lt;/p&gt;

&lt;p&gt;We will start by creating our project via CRA 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;npx create-react-app &lt;span class="nt"&gt;--template&lt;/span&gt; typescript cra-template-tailwind-twin-goober
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are creating a clean CRA application so we can have a testing environment for our custom tooling instead of cloning one of the two templates locally and modifying it.&lt;/p&gt;

&lt;p&gt;Keep in mind that  the naming convention has to follow this standard: &lt;strong&gt;cra-template-[your_template_name]&lt;/strong&gt; or in our case &lt;strong&gt;cra-template-tailwind-twin-goober&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This way CRA will know that it's an actual template instead of an app. That is a reason why typescript template is named &lt;strong&gt;cra-template-typescript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note that during installation cra-template prefix is comitted as seen with typescript template.&lt;/p&gt;

&lt;p&gt;Let's start modifying 👷🏼&lt;/p&gt;

&lt;p&gt;Navigate to package.json and add the following scripts under scripts section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"cleanup-template"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rm -rf ./_template_"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"generate-dirs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mkdir _template_ &amp;amp;&amp;amp; cd _template_ &amp;amp;&amp;amp; mkdir template &amp;amp;&amp;amp; cd template &amp;amp;&amp;amp; mkdir src &amp;amp;&amp;amp; mkdir public &amp;amp;&amp;amp; cd .. &amp;amp;&amp;amp; cd .."&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"copy-resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a ./src/. _template_/template/src &amp;amp;&amp;amp;  cp -a ./public/. _template_/template/public &amp;amp;&amp;amp; cp template.json _template_/ &amp;amp;&amp;amp; cp template-package.json _template_/package.json &amp;amp;&amp;amp; cp .gitignore _template_/template/gitignore"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"generate-template"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run cleanup-template &amp;amp;&amp;amp; npm run generate-dirs &amp;amp;&amp;amp; npm run copy-resources"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These scripts will help us generate our custom template on demand.&lt;/p&gt;

&lt;p&gt;Now let's examine each script and what it does.&lt;/p&gt;

&lt;p&gt;First on our list is &lt;strong&gt;cleanup-template&lt;/strong&gt; script. This script's job is to clean up the template directory in our project. This one will be very useful for generating new templates over and over.&lt;br&gt;
Next script is &lt;strong&gt;generate-dirs&lt;/strong&gt;. This script is used to generate our folders, starting with &lt;em&gt;template&lt;/em&gt; which is our template's route folder then template folder inside of it with source and public folders.&lt;br&gt;
Next up is the &lt;strong&gt;copy-resources&lt;/strong&gt; script. The job of this script is to copy all our files and move them to the template folder following CRA structure.&lt;br&gt;
Last on our list is &lt;strong&gt;generate-template&lt;/strong&gt; script, this one just combines previous scripts into one single execution.&lt;br&gt;
This script will be used each time we want to publish/update our template on npm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beginner Tip&lt;/strong&gt;: you run these scripts by typing the npm run command followed by script name. Ex. npm run generate-template &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep in mind&lt;/strong&gt; that these scripts are not final and we will be updating them as we progress further in this guide.&lt;/p&gt;

&lt;p&gt;In order for the CRA template to work we will need to add two new files template.json and package.json. We will start by creating a template.json file in our root directory and copying the content of &lt;a href="https://github.com/facebook/create-react-app/blob/master/packages/cra-template/template.json" rel="noopener noreferrer"&gt;template.json&lt;/a&gt; of our CRA template of choice. &lt;/p&gt;

&lt;p&gt;Next up we are going to create a package.json file in our root directory but since we already have one created by CRA we are going to name this one template-package.json.&lt;br&gt;
Same as with template.json we are going to copy &lt;a href="https://github.com/facebook/create-react-app/blob/master/packages/cra-template/package.json" rel="noopener noreferrer"&gt;package.json&lt;/a&gt; found in CRA template.&lt;/p&gt;

&lt;p&gt;We now effectively have the exact same copy of the CRA template as the one used to create our app initially.&lt;/p&gt;

&lt;p&gt;Let's give it a go 😄&lt;/p&gt;

&lt;p&gt;You can run locally your template with 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;// generates template
npm run generate-template

// creates a new react app with your custom template
npx create-react-app &lt;span class="nt"&gt;--template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;file:/path/to/your/dir/cra-template-tailwind-twin-goober/_template_
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is it guys now we have a starting point for our template. Now we can slowly add our tools and customize the template we have already created.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding ESLint, Prettier and Husky
&lt;/h3&gt;

&lt;p&gt;We are going to start by installing ESLint globally with 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;npm i eslint &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can initialize eslint 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;npx eslint &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted with some questions on how you plan to use ESLint.&lt;br&gt;
As this is not really the subject of this guide I will just leave my answers down below.&lt;br&gt;
Feel free to comment down below if you have any troubles with the setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How would you like to use ESLint?&lt;/strong&gt;&lt;br&gt;
A: To check syntax, find problems, and enforce code style&lt;br&gt;
&lt;strong&gt;What type of modules does your project use?&lt;/strong&gt;&lt;br&gt;
A: JavaScript modules (import/export)&lt;br&gt;
&lt;strong&gt;Which framework does your project use?&lt;/strong&gt;&lt;br&gt;
A: React&lt;br&gt;
&lt;strong&gt;Does your project use TypeScript?&lt;/strong&gt;&lt;br&gt;
A: Yes&lt;br&gt;
&lt;strong&gt;Where does your code run?&lt;/strong&gt;&lt;br&gt;
A: Browser&lt;br&gt;
&lt;strong&gt;How would you like to define a style for your project?&lt;/strong&gt;&lt;br&gt;
A: Use a popular style guide&lt;br&gt;
&lt;strong&gt;Which style guide do you want to follow?&lt;/strong&gt;&lt;br&gt;
A: Airbnb (matches closely my code style)&lt;br&gt;
&lt;strong&gt;What format do you want your config file to be in?&lt;/strong&gt;&lt;br&gt;
A: JSON&lt;/p&gt;

&lt;p&gt;That's it 😊 We have completed setting up our linter. All we need to do is include it now in our template resource script. If you navigate to your project root you can see an .eslintrc.json file. This file contains your linting rules. &lt;/p&gt;

&lt;p&gt;We are going to add ESLint to our template by modifying our copy-resources script like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"copy-resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a ./src/. _template_/template/src &amp;amp;&amp;amp;  cp -a ./public/. _template_/template/public &amp;amp;&amp;amp; cp template.json _template_/ &amp;amp;&amp;amp; cp template-package.json _template_/package.json &amp;amp;&amp;amp; cp .gitignore _template_/template/gitignore &amp;amp;&amp;amp; cp .eslintrc.json _template_/template/"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since ESLint installed some dependencies in our project we also need to include them in our template.&lt;br&gt;
We can modify our projects dependencies by modifying template.json file&lt;br&gt;
Navigate to template.json and create a new field called devDependencies and copy the same named field in package.json.&lt;br&gt;
Also since we are running our custom linter we can remove &lt;strong&gt;eslintConfig&lt;/strong&gt; field from template.json.&lt;br&gt;
After these changes your template.json should look like this:&lt;/p&gt;

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

&lt;p&gt;Let's quickly add Prettier 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; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation is done navigate to the root directory and add &lt;strong&gt;.prettierrc.json&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Prettier configuration is going to depend on your coding style, for the sake of simplicity i will share a &lt;a href="https://github.com/rmurati/cra-template-tailwind-twin-goober/blob/main/.prettierrc.json" rel="noopener noreferrer"&gt;link&lt;/a&gt; to mine.&lt;/p&gt;

&lt;p&gt;We need to modify the copy-resources script as well as template.json and add the prettier with all its dependencies as a resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"copy-resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a ./src/. _template_/template/src &amp;amp;&amp;amp;  cp -a ./public/. _template_/template/public &amp;amp;&amp;amp; cp template.json _template_/ &amp;amp;&amp;amp; cp template-package.json _template_/package.json &amp;amp;&amp;amp; cp .gitignore _template_/template/gitignore &amp;amp;&amp;amp; cp ./{.eslintrc.json,.prettierrc.json} _template_/template/ "&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last on our list is husky. We will use husky together with the power of git hooks to automatically format and fix our files on every commit. Since we don't want all our files to be linted on every commit we will install a small package called lint-staged. Thanks to this package we can lint only staged files.&lt;/p&gt;

&lt;p&gt;To install husky and lint-staged 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;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; husky lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installation update template.json with your new dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"husky"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"pre-commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lint-staged"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"./src/**/*.{ts,js,jsx,tsx}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"npm run lint --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"npm run format"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see from the code we added two new fields called husky and lint-staged.&lt;br&gt;
These two fields in conjunction with one another will allow us to achieve our desired effect.&lt;/p&gt;

&lt;p&gt;Cool 🎉 🎉. Now whenever we use this template our code style tooling will be ready to go out of the box.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding tailwindcss with twin.macro and goober
&lt;/h3&gt;

&lt;p&gt;We are going to use &lt;a href="https://www.npmjs.com/package/tailwindcss" rel="noopener noreferrer"&gt;tailwindcss&lt;/a&gt; due to the fact that it is a utility first css framework, fully configurable and customisable.&lt;br&gt;
It plays really well with React’s philosophy on component composition hence the reason why it's my css framework of choice.&lt;br&gt;
On the other hand &lt;a href="https://www.npmjs.com/package/tailwindcss" rel="noopener noreferrer"&gt;twin.macro&lt;/a&gt; unlocks the full potential of tailwind css by allowing us to generate styled components from tailwind utilities. Since this is just a babel plugin it leaves no code behind.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/goober" rel="noopener noreferrer"&gt;Goober&lt;/a&gt; is a fairly new kid on the block. It is a css-in-js library that we will use to help twin.macro generate our styles. The reasoning behind goober is its size or lack thereof. Goober, unlike styled-components of emotion, is around 1kb. Yep you heard me right 🤯🤯.&lt;/p&gt;

&lt;p&gt;We will start by installing tailwind like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to complete tailwindcss setup we will need a small yet powerful library called craco.&lt;br&gt;
Craco will allow us to reconfigure CRA as needed. We will use it to run postcss with autoprefixer and tailwindcss.&lt;/p&gt;

&lt;p&gt;Let's install craco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @craco/craco
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's navigate to template.json. We are going to modify a couple of things here.&lt;br&gt;
First we will add craco as our dependency and then move under scripts section and add the following scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"craco start"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"craco build"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"craco test"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"eject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts eject"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You need to modify package.json as well with the same changes!&lt;/p&gt;

&lt;p&gt;Besides that now we need to create a new file called &lt;strong&gt;&lt;em&gt;craco.config.js&lt;/em&gt;&lt;/strong&gt; and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// craco.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autoprefixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="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;Next step is going to be initializing tailwind css. Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tailwindcss-cli@latest init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a basic &lt;strong&gt;tailwind.config.js&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Now would be a good time to update our copy-resources script with tailwind and craco configs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"copy-resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a ./src/. _template_/template/src &amp;amp;&amp;amp;  cp -a ./public/. _template_/template/public &amp;amp;&amp;amp; cp template.json _template_/ &amp;amp;&amp;amp; cp template-package.json _template_/package.json &amp;amp;&amp;amp; cp .gitignore _template_/template/gitignore &amp;amp;&amp;amp; cp ./{.eslintrc.json,.prettierrc.json,craco.config.js,tailwind.config.js} _template_/template/ "&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets install twin.macro now 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;npm i twin.macro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order for twin.macro to do its magic we need babel as well as babel macro plugin. We will install them 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;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; babel-plugin-macros @babel/core @agney/babel-plugin-goober-css-prop babel-plugin-twin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least install goober 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;npm i goober
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now would be a good moment to update our dependencies in template.json and add a new field called &lt;strong&gt;babelMacros&lt;/strong&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"babelMacros"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"twin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tailwind.config.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"preset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"goober"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To complete twin.macro setup we will create a &lt;strong&gt;.babelrc.json&lt;/strong&gt; file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .babelrc.json&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agney/babel-plugin-goober-css-prop&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-plugin-macros&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-plugin-twin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add this file to copy-resources script as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"copy-resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cp -a ./src/. _template_/template/src &amp;amp;&amp;amp;  cp -a ./public/. _template_/template/public &amp;amp;&amp;amp; cp template.json _template_/ &amp;amp;&amp;amp; cp template-package.json _template_/package.json &amp;amp;&amp;amp; cp .gitignore _template_/template/gitignore &amp;amp;&amp;amp; cp ./{.eslintrc.json,.prettierrc.json,craco.config.js,tailwind.config.js,babel.config.json} _template_/template/ "&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;",
...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now navigate to &lt;strong&gt;src/index.ts&lt;/strong&gt; file and add the following line to import tailwind css base.&lt;br&gt;
While we are here we are going to set up goober as well.&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="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;ReactDOM&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-dom&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setup&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;goober&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss/dist/base.min.css&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;App&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;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// setup goober&lt;/span&gt;
&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&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;App&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is it guys. We have finished our template with custom boilerplate code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing template to npm
&lt;/h3&gt;

&lt;p&gt;This is it people. We are in the endgame now (any MCU fans?).&lt;/p&gt;

&lt;p&gt;As the final step let's deploy our template to npm.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; and create an account.(It's free)&lt;/p&gt;

&lt;p&gt;After creating an account open up your terminal and run generate-template script.&lt;/p&gt;

&lt;p&gt;Once the template is generated we can navigate to &lt;em&gt;template&lt;/em&gt; folder in our terminal.&lt;/p&gt;

&lt;p&gt;Type the following command to login to npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done now we can publish our package like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it guys. Our custom template is ready to be installed.&lt;/p&gt;

&lt;p&gt;If you have any questions feel free to comment down below and I will get back to you as soon as I can.&lt;/p&gt;

&lt;p&gt;Happy hacking guys 😊&lt;/p&gt;

&lt;p&gt;Links:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/cra-template-tailwind-twin-goober" rel="noopener noreferrer"&gt;npm link of cra-template-tailwind-twin-goober&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/ornio-no/cra-template-tailwind-twin-goober" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>tailwindcss</category>
      <category>npm</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Simplify condition rendering in React.js
</title>
      <dc:creator>Redžep Murati</dc:creator>
      <pubDate>Thu, 08 Jul 2021 07:43:03 +0000</pubDate>
      <link>https://dev.to/ornio/simplify-condition-rendering-in-react-js-33l8</link>
      <guid>https://dev.to/ornio/simplify-condition-rendering-in-react-js-33l8</guid>
      <description>&lt;p&gt;As a professional developer you are forced to stay up to date with the latest trends in technology. This year I've added Svelte to my bucket list as a new framework to learn.&lt;br&gt;
While researching Svelte I was surprised by the way they handle condition rendering.&lt;br&gt;
Take a look at this example found in their docs:&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="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loggedIn&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;toggle&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;Log&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sr"&gt;/if&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is neatly wrapped with if clause and separated from normal flow.&lt;/p&gt;

&lt;p&gt;After a quick prototyping I present to you the most powerful component I have ever written, an IF component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;   &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By offloading condition into a separate component this will improve code cleanness and readability by quite a margin (for free).&lt;/p&gt;

&lt;p&gt;Let’s imagine the Svelte example in our React app. It would go something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="err"&gt;…&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loggedIn&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Log&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;This is not an end of the world issue when you have just one condition but as our apps grow, so do the conditions. &lt;/p&gt;

&lt;p&gt;Take a look at the same component now refactored to use IF:&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="err"&gt;…&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IF&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loggedIn&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Log&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/IF&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Now it’s easier to track down conditions and debug faulty ones, plus the code looks way cleaner now that conditions are gone from JSX. &lt;/p&gt;

&lt;p&gt;Hope you found this helpful ❤️&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>#SoMeIt</title>
      <dc:creator>Trine Hoel</dc:creator>
      <pubDate>Wed, 30 Jun 2021 15:09:21 +0000</pubDate>
      <link>https://dev.to/ornio/someit-4b30</link>
      <guid>https://dev.to/ornio/someit-4b30</guid>
      <description>&lt;h6&gt;
  
  
  If I tell you that the proportion who use the internet has risen 85% from 1997 to 2020, it may not surprise you. The Internet and social media have become an addiction and a necessity for everyone, regardless of age. With so many people in the world using the internet, the topic of honesty is raised frequently.
&lt;/h6&gt;

&lt;p&gt;As a committed marketer, I would not be so without telling my opinion about exactly my field - &lt;em&gt;marketing&lt;/em&gt;. Marketing can be defined and understood as the activities one does to reach the audience, as well as increase the visibility of the company. The work involves recognizing the needs of the audience and giving them exactly what they need through our products and services. &lt;/p&gt;

&lt;p&gt;Since reaching out to customers plays a huge role, the way you decide to approach them has also great importance therefore carrying your message with honesty and integrity plays a major role. The importance of this is great and it is therefore important to carry out their work in an honest way, by using social media for an honest purpose.&lt;/p&gt;

&lt;p&gt;If the hashtag &lt;em&gt;#SOMEIT&lt;/em&gt; does not make perfect sense, the point is to be what one pretends to be. SoMe is the abbreviation for social media and is the inspiration for &lt;em&gt;#SOMEIT&lt;/em&gt;. If you post it on SoMe, so be (Me) it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tell the truth&lt;/strong&gt;&lt;br&gt;
As a company, you will always want to deliver fantastic results and mastery to gain more followers, but it is important for us in Ornio to distinguish between what is truth and what is a facade. It is a well-known fact that social media is adorned with facades and glossy images of everyday life, regardless of whether it is individuals or companies, success can come to anyone - regardless. Nevertheless, we want to market ourselves for the company we are. So when using social media, the goal is to market our business by sharing our journey and creating relationships in an honest way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Success?&lt;/strong&gt;&lt;br&gt;
Is being an honest Business the recipe for success? Both yes and no. The benefits of using social media are many, including increasing visibility, gaining insight and increasing loyalty. By providing sincere information about the benefits we provide, as well as the values ​​we stand for, we will have followers who share the same opinion that we share in our posts. It is these followers we create content for, and will share our journey with through various blog posts and SoMe posts. It is also worth mentioning that not all visibility is good visibility. Ornio wants to create interest and commitment for people who have the same interests and values ​​as us, and it is this visibility our goal is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transparency&lt;/strong&gt;&lt;br&gt;
We want to post what is important to us and the values ​​we stand for, and through this honesty we will get the supporters who motivate us to continue with the work we do. This openness also involves feedback from our supporters, and channels that are open to dialogue. We want to connect with our community and give them the feeling of sincerity. It is therefore important for us that our supporters know that there are people behind the posts, not just preconstructed data that only looks for the results.&lt;/p&gt;




&lt;p&gt;In conclusion, I would like to take this opportunity to encourage all companies to use the hashtag &lt;em&gt;#SOMEIT&lt;/em&gt;, to front honestly for companies on social media. For customers, this is exactly what can be most significant.&lt;/p&gt;

&lt;p&gt;Sources:&lt;br&gt;
(&lt;a href="https://www.medienorge.uib.no/statistikk/medium/ikt/347"&gt;https://www.medienorge.uib.no/statistikk/medium/ikt/347&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>culture</category>
    </item>
    <item>
      <title>Container/View Pattern in React inc.hooks</title>
      <dc:creator>Redžep Murati</dc:creator>
      <pubDate>Wed, 23 Jun 2021 09:14:15 +0000</pubDate>
      <link>https://dev.to/ornio/container-view-pattern-in-react-inc-hooks-5404</link>
      <guid>https://dev.to/ornio/container-view-pattern-in-react-inc-hooks-5404</guid>
      <description>&lt;p&gt;We at Ornio love clean, readable code. In order to achieve this we are in constant search for new techniques and methods to make our code as robust as possible.&lt;/p&gt;

&lt;p&gt;Few years ago we switched from Ember to React. At first React seemed like strange unexplored territory where everything made sense and nothing did.&lt;br&gt;
Questions started popping up. What's the best way to make a component ? When to make one ? How to keep them as reusable as possible ?&lt;/p&gt;

&lt;p&gt;In search of answers I came across this article by Dan Abramov on Presentational and Container components. After reading it I instantly fell in love with the idea that it represented.&lt;/p&gt;
&lt;h4&gt;
  
  
  So what is the Container/View pattern?
&lt;/h4&gt;

&lt;p&gt;Container/View pattern (also known as  Presentational/Container, Thick/thin, Smart/Dumb) is a technique of splitting components into 'Containers' which are responsible for any stateful logic and data fetching and 'Views' which are responsible for data presentation.&lt;/p&gt;

&lt;p&gt;If used right this pattern allows for immense scaling options in React applications. By keeping views clean of any logic we can reuse them as much as we want. But also now that all our logic is contained inside a container it allows us for faster and easier debugging.&lt;/p&gt;

&lt;p&gt;Here is a simple example on how to implement this pattern.&lt;/p&gt;

&lt;p&gt;Let's start by creating our view component. In our case it will be a simple user card showing a profile picture, name, location, gender and email of a user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;style&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;./Card.module.css&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;Card&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
      &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardLocation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardContact&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardMail&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`email: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cardGender&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`gender: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;gender&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;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;Card&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's add some style to make it pretty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fit-content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;119&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;163&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.06&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;119&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;163&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardImage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardContact&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardTitle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#112340&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardLocation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#112340&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cardMail&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.cardGender&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#112340&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.65&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;Voila. Our card is finished and ready to use.&lt;/p&gt;

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

&lt;p&gt;Now here is where the magic happens. We are going to create a new component called CardContainer. Inside this component is where the logic happens. We are going to fetch a user from a random user api and display data to our card.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&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="nx"&gt;useEffect&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="s2"&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;axios&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;axios&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;Card&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;@components/Card&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;CardContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUserData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://randomuser.me/api/&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&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;setUserData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&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="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;picture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;fetchData&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Card&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CardContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see by isolating all the logic in the container our view component is clean and ready to be reused as many times as we wish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction of hooks in React
&lt;/h2&gt;

&lt;p&gt;As we can see from Dan's blog with the introduction of hooks there is no need to package components like this. Since hooks allow us to isolate logic inside them and then just call them on demand, the need for a container is slowly fading away.&lt;/p&gt;

&lt;p&gt;But as great as hooks are, they do not solve every problem, hence the reason why this approach is still widely used.&lt;/p&gt;

&lt;p&gt;First let's move our container logic to a custom hook called useUserData.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&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="nx"&gt;useEffect&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="s2"&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;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useUserData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUserData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://randomuser.me/api/&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&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;setUserData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;country&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&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="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;picture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;fetchData&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userData&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks good right. Now our logic is inside a hook instead of a container.&lt;br&gt;
But how do I mix them now ? &lt;br&gt;
Well we can try making a wrapper.&lt;br&gt;
Let's do that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useUserData&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;@hooks/useUserData&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;Card&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;@componets/Card&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;UserCardContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUserData&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Card&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;UserCardContainer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now isn't this just another container? This creates a new arbitrary division where now ur logic is separated in 3 different files.&lt;br&gt;
To me this was a really hacky way and it just wasn't as clean as i was hoping for.&lt;br&gt;
I loved the idea of hooks and the idea of container/view pattern so I wasn't ready to give up yet. &lt;br&gt;
To the internet!&lt;br&gt;
After some digging online I have found a solution in the form of a library called react-hooks-compose.&lt;/p&gt;

&lt;p&gt;What this library allows us to do is compose our views with our custom hooks removing the need for a container.&lt;/p&gt;

&lt;p&gt;Let's compose our useUserData hook and Card component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;composeHooks&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;react-hooks-compose&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useUserData&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="s2"&gt;@hooks/useUserData&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;Card&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;@components/Card&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;CardContainer&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;@containers/CardContainer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// composing card with our hook&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ComposedCard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;composeHooks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;useUserData&lt;/span&gt; &lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Card&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ComposedCard&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CardContainer&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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="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;Success at last 🎉 🎉&lt;/p&gt;

&lt;p&gt;Personally I think that container/view pattern in any shape or form is a great way to separate the concerns and keep your code as reusable as possible.&lt;br&gt;
We at Ornio love this approach and will continue to use it as it helped us scale faster and it made building and testing components so much easier.&lt;/p&gt;

&lt;p&gt;Hope you found this article helpful.&lt;/p&gt;

&lt;p&gt;Links:&lt;br&gt;
&lt;a href="https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0" rel="noopener noreferrer"&gt;Dan's original post&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/react-hooks-compose" rel="noopener noreferrer"&gt;react-hooks-compose&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gist.github.com/rmurati/6ee7a319f412f3d0b0c7f3dbb57b6d18" rel="noopener noreferrer"&gt;code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>hooks</category>
    </item>
    <item>
      <title>Ornio´s truths</title>
      <dc:creator>Trine Hoel</dc:creator>
      <pubDate>Fri, 11 Jun 2021 13:09:51 +0000</pubDate>
      <link>https://dev.to/ornio/ornio-s-truths-5bd0</link>
      <guid>https://dev.to/ornio/ornio-s-truths-5bd0</guid>
      <description>&lt;h6&gt;
  
  
  When creating Ornio's values, the goal was to be able to utilize the values for own development and better collaboration. The values ​​should function as a set of rules in the workplace, and if challenges arose, the values ​​should put us back on track. For our partners and customers, the values ​​should show what we stand for and how we want to deliver our best - and so it has worked. Whether it's potential customers or colleagues, we have four truths that we value highly. Within my own field, I want to shed light on our four truths and how we want to market ourselves in the future.
&lt;/h6&gt;

&lt;p&gt;&lt;strong&gt;We innovate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first truth is that our services and products should not be available everywhere. We want to constantly develop and improve, so that we are at the top of every wave. For marketing, this truth will stand for how we continuously want to find new ways to engage, communicate and be creative. We want to be regularly updated and create solutions for how we can reach the target group in the best possible way. Social media is constantly growing, and every day new trends are created. It is therefore very important to have an interest in the subject and the challenges the market offers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We are committed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are committed to delivering a unique product that we at Ornio are proud to present. This requires cooperation and loyalty, both internally and externally in the company. As an interdisciplinary team, it is therefore important to share knowledge to achieve results and utilize our burning interest in achieving the goals. Commitment involves, among other things, maintaining deadlines, fulfilling wishes and keeping agreements. We at Ornio use this truth to constantly remind ourselves that we are committed, for ourselves and others, to do our best.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We are credible&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The third truth is that we should be trustworthy and sincere at all times. For social media, this is a central value, where we want to convey sincere information and commitment in what we post. Nothing should be done halfway or feel wrong. For us, it is important that our followers and customers feel safe and taken care of, in the information we provide. Within the team, it is this value that makes us good, in that honesty makes the products and service better. Because if one does not show honesty, we will not be challenged by each other to do a better job.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're excellent&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This is a truth we are proud of. We at Ornio are good at what we do because we are a team. By learning from each other, collaborating, sharing knowledge and praising each other, we will always grow for the better. Knowledge is challenged by constantly new courses, collaboration is improved with weekly team building and patience is challenged with an eternally long period of home office in the pandemic.&lt;/p&gt;

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

&lt;p&gt;Finally, I would like to thank you for reading this blog post and encourage you to follow us further for more posts and updates. Feel free to send a message on social media if you have requests for content or blog posts, by using this &lt;a href="https://www.facebook.com/ornio.no"&gt;Link&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>values</category>
      <category>innovation</category>
      <category>culture</category>
    </item>
    <item>
      <title>Code review and clean coding principles at ORNIO</title>
      <dc:creator>EgzonaVllasaliu</dc:creator>
      <pubDate>Wed, 12 May 2021 10:24:39 +0000</pubDate>
      <link>https://dev.to/ornio/code-review-and-clean-coding-principles-48o7</link>
      <guid>https://dev.to/ornio/code-review-and-clean-coding-principles-48o7</guid>
      <description>&lt;p&gt;How to make a good review of the code? Where to start? What you should remember? Why is clean coding important?&lt;br&gt;
I will show you my practices which will help not only with the product itself, but also make wonders for the development team.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code review
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Code review helps give a fresh set of eyes to identify bugs and simple coding errors before your product gets to the next step, making the process for getting the software to the customer more efficient. Simply reviewing someone's code and identifying errors is great.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here at Ornio we use this guideline to do an organised code review.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ask open-ended questions instead of making strong or opinionated statements. Offer alternatives and possible workarounds that might work better for the situation without insisting those solutions are the best or only way to proceed. These reviews assume the reviewer might be missing something and ask for clarification instead of correction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once a reviewer completes their review, they can either mark it approved, block the review with change requests, or not set a specific status, leaving it in a “not yet approved” state. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexible on the practice: sometimes, certain comments are addressed by the author with a separate, follow-up code change. For changes that are more urgent than others, reviewers should try to make themselves available for quicker reviews.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave as many comments and questions as needed. If the revision does not address all of them, they will note those as well. When the conversation gets into a long back-and-forth, reviewers should try to switch to talking to the author in-person instead of  burning more time using the code review tool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proactively reach out to the person making the change after they do a first pass on the code and have lots of comments and questions. This will save a lot of time, misunderstandings, and hard feelings this way. The fact that there are many comments on the code indicates that there is likely some misunderstanding on either side. These kinds of misunderstandings are easier identified and resolved by talking things through.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it clear when changes are unimportant nitpicks. They usually mark comments like these distinctively, adding the “nit:” prefix to them. Too many of these can become frustrating and take the attention away from the more important parts of the review, so reviewers aim to not go overboard with these.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Realize that too many nitpicks are a sign of lack of tooling or a lack of standards. Reviewers who come across these frequently will look at solving this problem outside the code review process. For example, many of the common nitpick comments can be solved via automated linting. Those that cannot,  can usually be resolved by the team agreeing to certain standards and following them—perhaps even automating them, eventually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure that all engineers take part in the code review process—even those that might be working on solo projects. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have hard rules around no code making it to production without a code review—just as business logic changes don’t make it to production without automated tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It is the author’s responsibility to submit PRs that are easy to review in order not to waste reviewers’ time and motivation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scope and size. Changes should have a narrow, well-defined, self-contained scope that they cover exhaustively.

&lt;ul&gt;
&lt;li&gt;For example, a change may implement a new feature or fix a bug. Shorter changes are preferred over longer ones. If a PR makes substantive changes to more than ~5 files, or took longer than 1–2 days to write, or would take more than 20 minutes to review, consider splitting it into multiple self-contained PRs. &lt;/li&gt;
&lt;li&gt;For example, a developer can submit one change that defines the API for a new feature in terms of interfaces and documentation, and a second change that adds implementations for those interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Review fewer than 400 lines of code at a time.&lt;/li&gt;
&lt;li&gt;Do not review for more than 60 minutes at a time&lt;/li&gt;
&lt;li&gt;Only submit complete, self-reviewed (by diff), and self-tested PRs (Authors should annotate source code before the review). In order to save reviewers’ time, test the submitted changes (i.e., run the test suite) and make sure they pass all builds as well as all tests and code quality checks, both locally and on the CI servers, &lt;em&gt;before assigning reviewers&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;It is customary for the committer to propose one or two reviewers who are familiar with the code base. Often, one of the reviewers is the project lead or a senior engineer.&lt;/li&gt;
&lt;li&gt;Project owners should consider subscribing to their projects in order to get notified of new PRs. &lt;/li&gt;
&lt;li&gt;As a reviewer, it is your responsibility to enforce coding standards and keep the quality bar up.&lt;/li&gt;
&lt;li&gt;Reviewing code is more of an art than a science. The only way to learn it, is to do it; an experienced reviewer should consider putting other less experienced reviewers on their changes and have them do a review first.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Maintainability
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Read the tests. If there are no tests and there should be, ask the author to write some. Truly untestable features are rare, while untested implementations of features are unfortunately common. Check the tests themselves: are they covering interesting cases? Are they readable? Does the PR lower overall test coverage? Think of ways this code could break. Style standards for tests are often different from core code, but still important.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Does this code need integration tests? Sometimes, code can’t be adequately tested with unit tests alone, especially if the code interacts with outside systems or configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Code Reviews for New Joiners
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The codebase is new, the style of programming is  different than before, and people review your code very differently. So should code reviews be gentler for new starters, to get them used to the new environment, or should they keep the bar just as high, as it is for everyone else?

&lt;ul&gt;
&lt;li&gt;Use the same quality bar and approach for everyone, regardless of their job title, level or when they joined the company. Following the above, code reviews have a kind tone, request changes where needed, and will reach out to talk to reviewers when they have many comments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Clean coding
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Decide on the indentation and keep it that way, follow standard conventions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code should be divided into logical units and it’s important to keep the style consistent throughout the whole document. In most of the programming languages, spaces and indentations do not affect the function. If you are using an IDE, it is recommended that you create a formatted config so everyone uses the same one.&lt;/li&gt;
&lt;li&gt;Make comments

&lt;ul&gt;
&lt;li&gt;Comments will help you and others understand why you did what you did. 

&lt;ul&gt;
&lt;li&gt;Always try to explain yourself in code.&lt;/li&gt;
&lt;li&gt;Don't be redundant.&lt;/li&gt;
&lt;li&gt;Don't add obvious noise.&lt;/li&gt;
&lt;li&gt;Don't use closing brace comments.&lt;/li&gt;
&lt;li&gt;Don't comment out code. Remove it instead.&lt;/li&gt;
&lt;li&gt;Use as explanation of intent.&lt;/li&gt;
&lt;li&gt;Use as clarification of code.&lt;/li&gt;
&lt;li&gt;Use as warning of consequences.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Consistent name scheme

&lt;ul&gt;
&lt;li&gt;Be consistent. If you do something a certain way, do all similar things in the same way. Naming needs to stay consistent, otherwise, it will be very difficult to find things inside the document.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Don’t repeat code

&lt;ul&gt;
&lt;li&gt;Repeating code will make your document very long and it will break the reading flow. If you have pieces of code that will be used more than once, it is preferable to make a separate file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Avoid writing long code lines

&lt;ul&gt;
&lt;li&gt;Writing long lines of code makes it very difficult to read, moving back and forth horizontally, losing any sense of what it’s actually written. Style and indentation will help with this.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Break down a big task into smaller chunks

&lt;ul&gt;
&lt;li&gt;A whole new feature will never be just a few lines long. Even with comments, a 500-lines function will still be a pain to browse, understand and edit.
Your best choice is to break down the big task into a smaller chunk of code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Organize your program into smaller files

&lt;ul&gt;
&lt;li&gt;Having a file with thousands of lines of code doesn’t help anyone, but broken down into shorter files organized based on function or feature will help you get right to the point when something needs fixing. Having the whole code organized in files and folders is very good for maintainability, especially if different teams and people are working on it.

&lt;ul&gt;
&lt;li&gt;Small.&lt;/li&gt;
&lt;li&gt;Do one thing.&lt;/li&gt;
&lt;li&gt;Use descriptive names.&lt;/li&gt;
&lt;li&gt;Prefer fewer arguments.&lt;/li&gt;
&lt;li&gt;Have no side effects.&lt;/li&gt;
&lt;li&gt;Don't use flag arguments. Split method into several independent methods that can be called from the client without the flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Keep it simple, write clever code that is also readable

&lt;ul&gt;
&lt;li&gt;Write clever code, but the main focus should be on readability and maintainability. If the code is kept short it is easier to go through, but if it’s too smart, it will take too much time to understand and edit it. You know that your code was too clever if you can’t read it after 3 months. So be clever but not too much!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Code refactoring

&lt;ul&gt;
&lt;li&gt;Every developer knows this – you write some code because you want to finish the feature and in the end, it works. When you then look at it after some time you think – did I really write that? I could have shortened it so much! So you start rewriting that piece of code better, probably shorter, without changing any functionality.  &lt;em&gt;Ps. It is the developer’s responsibility to create tasks for refactoring the code&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delete unnecessary code

&lt;ul&gt;
&lt;li&gt;You wrote new code, great. Is the new code working? If yes, then just delete the old one! There is no point in keeping the old code, and comment it out. It will just look messy and unnecessarily long.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Must avoid doing: 

&lt;ul&gt;
&lt;li&gt;Rigidity. The software is difficult to change. A small change causes a cascade of subsequent changes.&lt;/li&gt;
&lt;li&gt;Fragility. The software breaks in many places due to a single change.&lt;/li&gt;
&lt;li&gt;Immobility. You cannot reuse parts of the code in other projects because of involved risks and high effort.&lt;/li&gt;
&lt;li&gt;Needless Complexity.&lt;/li&gt;
&lt;li&gt;Needless Repetition.&lt;/li&gt;
&lt;li&gt;Opacity. The code is hard to understand.&lt;/li&gt;
&lt;li&gt;Try to avoid temporary variables.

&lt;ul&gt;
&lt;li&gt;Using too many temporary variables can cause memory leaks, because of that try to use temporary variables only when:

&lt;ul&gt;
&lt;li&gt;statements are getting too long and too complex&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Don’t use temporary variables when: 

&lt;ul&gt;
&lt;li&gt;Return a value from a function: &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;                                &lt;strong&gt;Don’t do&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;name&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;message&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;                                &lt;strong&gt;Do&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>codereview</category>
      <category>cleancoding</category>
      <category>pullrequest</category>
      <category>ornio</category>
    </item>
    <item>
      <title>IE adds double XMLNS on SVG markup when converting to string</title>
      <dc:creator>Flamur Mavraj</dc:creator>
      <pubDate>Mon, 10 May 2021 02:29:47 +0000</pubDate>
      <link>https://dev.to/ornio/ie-adds-double-xmlns-on-svg-markup-when-converting-to-string-5fmi</link>
      <guid>https://dev.to/ornio/ie-adds-double-xmlns-on-svg-markup-when-converting-to-string-5fmi</guid>
      <description>&lt;p&gt;We where tasked/needed to serialize SVG files on a project we are working on, and while the first implementation worked well on most (normal) browsers, it did not take too long time before we got some complains that our images where not being displayed properly.&lt;/p&gt;

&lt;p&gt;After some debugging we found out that all these cases where related to users using IE. And after dusting of my Windows laptop and started testing we could reproduce the issue ❤️ (as developer I get a relief when I can reproduce an bug)&lt;/p&gt;

&lt;p&gt;After a quick search on Google for &lt;code&gt;IE svg adding double xmlns&lt;/code&gt; following two links helped understanding the issue and led to a fix:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/19610089/unwanted-namespaces-on-svg-markup-when-using-xmlserializer-in-javascript-with-ie"&gt;Unwanted namespaces on SVG markup when using XMLSerializer in JavaScript with IE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/17265376/highcharts-adds-duplicate-xmlns-attribute-to-svg-element-in-ie"&gt;Highcharts adds duplicate xmlns attribute to SVG element in IE&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  First implementation (Does NOT work on IE)
&lt;/h2&gt;

&lt;p&gt;We do use Figma to design and create our SVG's, when exporting, the SVG contains the &lt;code&gt;xmlns&lt;/code&gt;-tag by default.&lt;/p&gt;

&lt;p&gt;Here is an SVG example showing a red circle where the &lt;code&gt;xmlns&lt;/code&gt;-tag is already set:&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;svg&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"40"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The serialize function we used is straight forward using &lt;code&gt;XMLSerializer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;svgSerialize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SVGSVGElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLSerializer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;serializeToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in following result:&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;svg&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"40"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as said this worked perfectly on all other browsers expect Internet Explorer. Here is the result of same image on IE:&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;svg&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"40"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes you spotted right, yet another &lt;code&gt;xmlns="http://www.w3.org/2000/svg"&lt;/code&gt;-tag has been added to the SVG :(&lt;/p&gt;

&lt;p&gt;Browsers are strict on XML parsing and therefor the above image will not be displayed!&lt;/p&gt;

&lt;p&gt;After some trial and errors here is how we fixed the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;First we removed &lt;code&gt;xmlns&lt;/code&gt; tag from our SVG:&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;svg&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;cx=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;cy=&lt;/span&gt;&lt;span class="s"&gt;"50"&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"40"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt; &lt;span class="na"&gt;stroke-width=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And our new svgImageToString function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;svgImageToString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SVGSVGElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Serialize the SVG object, this will add an xmlns on IE&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serialized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLSerializer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;serializeToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// We then do convert back the SVG serialized string to new SVG &lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DOMParser&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;newSvg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serialized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/svg+xml&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;newSvgEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newSvg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;SVGSVGElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// We check if the new SVG has xmlns if not we added to it&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;newSvgEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xmlns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
        &lt;span class="nx"&gt;newSvgEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xmlns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://www.w3.org/2000/svg&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="c1"&gt;// We serialize the new element again and return the result&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;XMLSerializer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;serializeToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newSvgEl&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;You are probably thinking why converting the SVG serialized string back to SVG object using DOMParser, due to our complex SVG's we where not able to detect and remove the double &lt;code&gt;xmlns&lt;/code&gt;-tag in another way (yes we tried with regex).&lt;/p&gt;

&lt;p&gt;Hope this will help others that will face this issue 😊&lt;/p&gt;

&lt;p&gt;Comment if you have other alternatives to the solution! &lt;/p&gt;

&lt;p&gt;Cheers :)&lt;/p&gt;

</description>
      <category>ie</category>
      <category>xmlserializer</category>
      <category>svg</category>
      <category>fix</category>
    </item>
    <item>
      <title>A Woman’s Guide to Project Management</title>
      <dc:creator>Aulore Hoxha</dc:creator>
      <pubDate>Fri, 07 May 2021 13:25:38 +0000</pubDate>
      <link>https://dev.to/ornio/a-woman-s-guide-to-project-management-5e83</link>
      <guid>https://dev.to/ornio/a-woman-s-guide-to-project-management-5e83</guid>
      <description>&lt;p&gt;Every Industry has its unique characteristics. Information Technology it's no different. But it’s always about effective management of workload and change, of a systematic approach to all stages and controlling of different types of events in the course of the project life cycle.&lt;/p&gt;

&lt;p&gt;If we want to answer a basic question first, &lt;strong&gt;what is project management?&lt;/strong&gt; In simple terms, it is getting work done in time and budget. If we would like to dive into some depth we say Project Management is the process of creating methodologies, using tools, and following processes to plan and execute projects in a successful way. Where we use teams and resources to complete tasks within the deadline, cost, and scope of the project, while we pass five main project life cycle stages: initiation, planning, execution, monitoring, control, and closure. &lt;/p&gt;

&lt;p&gt;In order to execute projects in a perfect manner we use different methodologies from &lt;strong&gt;Waterfall&lt;/strong&gt; to &lt;strong&gt;Kanban&lt;/strong&gt; to &lt;strong&gt;Scrum&lt;/strong&gt; and many others, all with the same objective; taking an idea and bringing it to fruition.&lt;/p&gt;

&lt;p&gt;Now, assuming we have mastered the technical skills of project management and implementation, is this all there is to know? And is this all we need to do?&lt;br&gt;
&lt;em&gt;Absolutely not&lt;/em&gt;! There are other &lt;strong&gt;key elements&lt;/strong&gt; we need to have in mind if we really want our projects to succeed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating proper communication channels&lt;/strong&gt;&lt;br&gt;
The ability to have the proper language on communicating important information to all relevant parties is crucial to project success. Remember that it's not always easy to get everyone on the same page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stimulating teams&lt;/strong&gt;&lt;br&gt;
Motivating people over the course of a long effort doesn't always come in handy. But it is important to motivate team members to do their best work even when deadlines get tight and projects get tricky &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adaptability&lt;/strong&gt;&lt;br&gt;
You need to know how to roll with the punches and make the necessary adjustments to move forward even in the face of unexpected issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resourcefulness&lt;/strong&gt;&lt;br&gt;
You don’t always have every tool to succeed in our projects but that should not stop you. Instead of giving up when you come across an issue you are not prepared about, you need to become determined to find a solution even if it takes a little elbow grease to do so. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Teamwork&lt;/strong&gt;&lt;br&gt;
Project management is all about working together in a group. Being cooperative, collaborating, creating easy environments to work in, talk to, and being fair to everyone else is as much important as any other element. &lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you have any questions or need help with Project Management ping me/us.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;We do also provide PM as a Service for our customers, If you are interested to find more contact me/us or schedule a meeting for more information.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://ornio.no/contact"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>agile</category>
      <category>management</category>
    </item>
    <item>
      <title>Applications that Ornio uses the most</title>
      <dc:creator>Diellëza Namani</dc:creator>
      <pubDate>Mon, 29 Mar 2021 14:10:02 +0000</pubDate>
      <link>https://dev.to/ornio/applications-that-ornio-uses-the-most-2ian</link>
      <guid>https://dev.to/ornio/applications-that-ornio-uses-the-most-2ian</guid>
      <description>&lt;p&gt;&lt;em&gt;Working from home has made us use even more tools that we would not necessarily have used if we would be working from the office. This process has made us become more aware of what is worth investing in and which ones can ease our work strategies and goals. These are the apps that we use and we figured you might find them handy:&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Hubstaff&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;(Ranking: 4.5/5)&lt;/p&gt;

&lt;p&gt;This application is the perfect one to monitor the work from home. It tracks the time and productivity by also being able to create reports and timesheets for more detailed information regarding what has been done. &lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hubstaff has more than 17 different reports that managers can use to gain insight into their operations, including daily productivity summary emails, which help managers monitor whether important deadlines are being met. It also helps managers see hours worked and work in progress without having to always check-in with their employees.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Jira &amp;amp; Bitbucket&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;(Rankings: 4.7/5 &amp;amp; 4.6/5)&lt;/p&gt;

&lt;p&gt;Jira is a project management tool for all agile teams. It provides Scrum and Kanban dashboards, roadmaps, and agile reporting. &lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Jira connects all people involved together and allows all team members to know what stage a project is at and how progress is going. Tasks can be easily prioritized, and it’s easy for team members to see what their next task is, reducing the amount of time wasted and improving productivity. &lt;/p&gt;




&lt;p&gt;Bitbucket is a Git-based code hosting and collaboration tool, built for teams. It also allows you to Build and test automatically with built-in continuous delivery and secure your code with frequent checks to prevent issues before they happen.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It provides a full-text search through all repositories of any account to locate a certain code since files are indexed. It allows you to push code up for review, be it for modifications, provide feedback, and approval. It can merge code allowing for teams to collaborate. After Pull request, you can merge it directly to your parent branch for testing the whole application. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Slack&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;(Ranking: 4.0/5)&lt;/p&gt;

&lt;p&gt;A communication management tool that allows colleagues to communicate with one another in different channels through messaging and video/voice calls. It is easy to use for all sizes of companies. It has integrations with other services like Google Drive, Office 365, and many others. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--96wYOA6i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l48pwtuakk31fkvlzl55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--96wYOA6i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l48pwtuakk31fkvlzl55.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With Slack, all you have to do is sign up and create a team. And, signing up is completely free. Once you’ve created your team, you create “channels”, which can be either private or public. Public channels are where your direct messages between you and your teammates live. If you have a client or contractor who needs to be kept in the loop, you can invite them, too. You can grant access permissions to outsiders with as many or as few privileges as your company sees fit.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Figma&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;(Ranking: 4.7/5) - based on Capterra&lt;/p&gt;

&lt;p&gt;Figma is the world’s first collaborative UI design tool built in the web browser. It supports excellent design, prototyping, and code generation tools.&lt;/p&gt;

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

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Figma works in a browser, making it extremely available and simple. Any unsaved file is automatically moved to drafts. The application allows multiple team members to work on a single project in real-time. Another feature of Figma is commenting. You can simply leave a comment right in the file, so your team can discuss the project remotely.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Whimsical&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;(Ranking: 4.7/5) - based on Capterra&lt;/p&gt;

&lt;p&gt;A collaborative virtual workspace that lets you create flowcharts, diagrams, and virtual sticky notes.&lt;br&gt;
Whimsical is perfect for remote workshops, user flows, user journey maps, lean canvas, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7hHl3IIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4hm6ok9yp9pul8426p1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7hHl3IIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4hm6ok9yp9pul8426p1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why this is important for your business:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Whimsical has a large open canvas just like any other design tool but the unique difference is the flexible libraries of elements used to generate flowcharts, wireframes, sticky notes, and mind maps, all in the same workspace. In addition to all the great features, this app has the ability to export visualizations in high resolution. The primary purpose of visualization is to communicate ideas, even office.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;Other applications that Ornio uses and recommends are:&lt;/strong&gt;
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;HubSpot, marketing, sales, and service software that helps any business grow rapidly. &lt;/li&gt;
&lt;li&gt;CloudApp, a cross-platform screen capture and screen recording desktop client that supports online storage and sharing.&lt;/li&gt;
&lt;li&gt;VSCode, a free open source code editor developed by Microsoft that allows easy debugging, multiple language syntaxes, code auto-completion, and easy git integration.&lt;/li&gt;
&lt;li&gt;Intellij IDEA, is an integrated development environment (IDE) that offers great code assistance like code autocompletion, syntax highlighting and robust debugger, while providing a rich plugin ecosystem and variety of language support.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>workfromhome</category>
      <category>ornio</category>
      <category>apps</category>
    </item>
    <item>
      <title>My journey as intern at Ornio</title>
      <dc:creator>EgzonaVllasaliu</dc:creator>
      <pubDate>Tue, 08 Sep 2020 06:16:12 +0000</pubDate>
      <link>https://dev.to/ornio/my-journey-as-intern-at-ornio-4bl0</link>
      <guid>https://dev.to/ornio/my-journey-as-intern-at-ornio-4bl0</guid>
      <description>&lt;p&gt;My name is Egzona, I just wanted to share with you my jurney as an intern at Ornio as Full-stack developer from June - August of 2020. &lt;/p&gt;

&lt;p&gt;I’m a 3rd-year Computer Engineer student from the University of Prishtina, Database and Artificial Intelligence branch.&lt;/p&gt;

&lt;p&gt;This was my second internship, first one as Web developer that I completed, so I had a bit of experience with one other company, and I really had a good idea about what I did and did not like about being an intern!&lt;/p&gt;

&lt;p&gt;I want to mention and thank everyone at &lt;a href="https://ickosovo.com/"&gt;ICK&lt;/a&gt; &amp;amp; partners for making this internship happen. After winning a scholarship and finishing successfully Coding Dojo bootcamp they gave me this opportunity, for which I will always be thankful.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Two Weeks (First phase)
&lt;/h3&gt;

&lt;p&gt;When I learned that I was going to be the only intern, I was excited to have the chance to shape the program and give feedback on what could be done better, and what to do more of. &lt;/p&gt;

&lt;p&gt;That being said, the onboarding process was by far the smoothest and most efficient of any internship I’ve done. I spent the first day meeting other employees.  In these meetings, they each went on a deep dive of their section to give me a real understanding of how everything works and how it all works together. This gave me a ton of insight into the organisation and its products. &lt;/p&gt;

&lt;p&gt;First two weeks I had to watch some tutorials to get to know better the technology that the company was using. This was my first phase as intern.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Actually Worked On (Phase two)
&lt;/h3&gt;

&lt;p&gt;After finishing the first phase, I had to work on an intern project and complete it by the end of the term. Beforehand I mentioned that I was interested in Full-stack development.&lt;/p&gt;

&lt;p&gt;The team, in dialog with me decided that it will be a good challenge for me to create an app that helps with task estimation while doing Sprint planning.&lt;/p&gt;

&lt;p&gt;Ornio uses Scrum and in Scrum methodology story points are used to estimate each task. Points follows the Fibonacci numbers when task are being estimated and therefore we named the project for just that, "FIBONACCI" :)&lt;/p&gt;

&lt;h3&gt;
  
  
  The stack
&lt;/h3&gt;

&lt;p&gt;On Front-End we used a JavaScript framework called React.js with TypeScript, while for the Back-End we used Hasura (an extremely lightweight, high performance product that gives instant realtime GraphQL APIs on a Postgres database) additionally to that we needed some more advance functionality and for that we used Node.js with Express.js and TypeScript as well. JWT was used for authentication.&lt;/p&gt;

&lt;p&gt;Live reloading of votes was accomplished using GraphQL subscription, which uses WebSockets under the hood. &lt;/p&gt;

&lt;p&gt;This was a really cool project to work on because it allowed me to work with lots of different tools and technologies in additional to the above mentioned such as Sass, Docker, Kubernetes and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  The functionality of the app
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg4cbi1wpnchq0edl2r1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg4cbi1wpnchq0edl2r1l.png" alt="Join or create a session" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fully use our application the users must be authenticated. Authenticated users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create and join sessions&lt;/li&gt;
&lt;li&gt;See their own sessions (sprint plannings), edit and delete them.&lt;/li&gt;
&lt;li&gt;Manage their personal informations.&lt;/li&gt;
&lt;li&gt;Can invite other teammates to a session (sprint planning) by sending them the session id/link. &lt;/li&gt;
&lt;li&gt;Within a session (sprint planning), creator (the moderator) can manage (create/edit/delete) stories and initiate voting so other teammates / players can estimate them. When all the players have voted on a story the votes are displayed and one of them selected as estimation for a story (task).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unauthenticated users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Join a session&lt;/li&gt;
&lt;li&gt;Invite a teammate&lt;/li&gt;
&lt;li&gt;Vote on ongoing sessions (sprint plannings).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwoxualm3bbd3fdcqllpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwoxualm3bbd3fdcqllpr.png" alt="Sprint estimation (voting)" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The entire process of working on this project was interesting and much different from my previous projects. I was responsible for the project from start to finish. Being a part of the entire lifecycle was an eye-opening experience to how the team/company operates, and it allowed me to learn who to go to and when to ask for help to get things done quickly and efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Experience
&lt;/h3&gt;

&lt;p&gt;When I got added to the Ornio Events calendar, I was surprised. There were multiple, interesting events every week which, as an intern, I definitely took advantage of. &lt;/p&gt;

&lt;p&gt;We had an event called “Competence Development”, where we used to learn new things everyday and then we had the chance to share our perspective of learning things with each other. &lt;/p&gt;

&lt;p&gt;Every day we had “Daily touch base event” where we used to inform each other what we have done during that day. Another cool event was “Social event” where we used to create quizzes using Kahoot!, and then “compete” with each other who will get more answers right. &lt;/p&gt;

&lt;p&gt;We also used Slack as communication tool with teammates, where we could chat and share resources that we found interesting, we also had a channel called team daily standup where we had to share with the team what we did yesterday and what we will be doing during that day, which I think was the best part because we had to start the day by planning it and then work toward things we said we will accomplish. &lt;/p&gt;

&lt;p&gt;I was included in everything the team did, so when people ask about my internship experience at Ornio, I tell them that I pretty much forgot that I was an intern.&lt;/p&gt;

&lt;h3&gt;
  
  
  The End and Future
&lt;/h3&gt;

&lt;p&gt;I learned a lot at Ornio about efficient web development processes, good code design and standards, all of which will be very helpful in my future career. &lt;/p&gt;

&lt;p&gt;I really enjoyed being part of the intern program at Ornio, and I’m looking forward to starting a full-time job as web developer soon!&lt;/p&gt;

&lt;p&gt;UPDATE: &lt;br&gt;
This article was write before I finished the internship, at the end of the internship Ornio offered me a position as Junior Full-stack developer and I accepted :)&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>node</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Node.js (Express) with TypeScript, Eslint, Jest, Prettier and Husky - Part 3</title>
      <dc:creator>Flamur Mavraj</dc:creator>
      <pubDate>Thu, 27 Aug 2020 07:12:56 +0000</pubDate>
      <link>https://dev.to/ornio/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-3-1l8c</link>
      <guid>https://dev.to/ornio/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-3-1l8c</guid>
      <description>&lt;p&gt;Let's start testing!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you should do testing?
&lt;/h2&gt;

&lt;p&gt;Before we continue with our setup I wanted to say some words regarding why you should do testing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yes testing is time consuming, and from time to time also hard but testing will save your ass in the long run. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Different testing techniques/tools exists and you should not (dont need to) cover all of them, also if use use multiple techniques/tools try to find a balance to not repeat your tests.&lt;/p&gt;

&lt;p&gt;Finding the balance on what to test and what not may be hard, specially if you work with large teams, so my suggestion is to set up some rules that everyone follows, here are some rules we at &lt;a href="https://ornio.no"&gt;Ornio AS&lt;/a&gt; try to embrace when it comes to testing Node.js applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All utility and service functions should be followed with a test, this should cover most of our functionality since we use Repository (service) pattern.&lt;/li&gt;
&lt;li&gt;Validations (we use Joi) should also be tested.&lt;/li&gt;
&lt;li&gt;Test Error handling.&lt;/li&gt;
&lt;li&gt;Test Middlewares using Supertest.&lt;/li&gt;
&lt;li&gt;Test critical Controllers using Supertest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❓ What about you? What do you test in your Node.js applications?&lt;/p&gt;

&lt;h1&gt;
  
  
  Jest
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Jest is a delightful JavaScript Testing Framework with a focus on simplicity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Installing Jest is easy, run the command below and you will install Jest including its type definition and Typescript Jest runner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -D jest @types/jest ts-jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to do some configuration, by initiating Jest to generate its config file, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jest --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer the questions as needed, here is our answers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose the test environment that will be used for testing&lt;/strong&gt;&lt;br&gt;
Node&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want Jest to add coverage reports?&lt;/strong&gt;&lt;br&gt;
No&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which provider should be used to instrument code for coverage?&lt;/strong&gt;&lt;br&gt;
Babel&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatically clear mock calls and instances between every test?&lt;/strong&gt;&lt;br&gt;
Yes&lt;/p&gt;

&lt;p&gt;This will generate a file called: &lt;code&gt;jest.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;clearMocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;moduleFileExtensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;roots&lt;/span&gt;&lt;span class="p"&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;&amp;lt;rootDir&amp;gt;/src&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;testEnvironment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^.+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;.tsx?$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts-jest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added some additional configuration in order to get &lt;code&gt;jest&lt;/code&gt; and &lt;code&gt;ts-jest&lt;/code&gt; running in our environment.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;transform&lt;/code&gt; is setup to look for &lt;code&gt;.ts&lt;/code&gt; and &lt;code&gt;.tsx&lt;/code&gt; files and use &lt;code&gt;ts-jest&lt;/code&gt; to run it.&lt;br&gt;
&lt;code&gt;moduleFileExtensions&lt;/code&gt; has also been updated with &lt;code&gt;ts&lt;/code&gt; and &lt;code&gt;tsx&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Alternative: Using preset to run ts-jest
&lt;/h3&gt;

&lt;p&gt;Instead of configuring &lt;code&gt;transform&lt;/code&gt; and &lt;code&gt;moduleFileExtensions&lt;/code&gt; you can define a preset in your jest.config.js file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ts-jest&lt;/code&gt; comes with 3 presets for you to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ts-jest/presets/default&lt;/code&gt; or &lt;code&gt;ts-jest&lt;/code&gt;: Its the default preset. TypeScript files will be handled by &lt;code&gt;ts-jest&lt;/code&gt;, leaving JavaScript files as-is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ts-jest/presets/js-with-ts&lt;/code&gt;: Both TypeScript and JavaScript files will be handled by &lt;code&gt;ts-jest&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ts-jest/presets/js-with-babel&lt;/code&gt;: TypeScript files will be handled by &lt;code&gt;ts-jest&lt;/code&gt; and JS files will be handled by Babel&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;jest.config.js&lt;/code&gt; will look like this when using default preset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;clearMocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;roots&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;rootDir&amp;gt;/src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;testEnvironment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;preset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts-jest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go ahead and add a test script in your &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we don't have any logic in our app, we are going to create a utility function just for this purpose in order to to write a test for it, let's create something that checks if a parameter is and number. Create a file &lt;code&gt;utils/isNumber.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;parseFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;isFinite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;Now lets write a test for it, We prefer to add tests on the same place as our code, &lt;code&gt;utils/isNumber.test.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isNumber&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="s2"&gt;./isNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isNumber Utils&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Its a number&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="o"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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="mf"&gt;1.345e17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Its not a number&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="o"&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;NaN&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&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="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;describe&lt;/code&gt; is used to group tests and &lt;code&gt;it&lt;/code&gt; defines a test. You can run multiple tests under &lt;code&gt;it&lt;/code&gt; but try to keep each test as small as possible for better readability. On the other hand &lt;code&gt;expect&lt;/code&gt; is a Jest function that is used to check a value and its used "always" with a matcher function, in our case &lt;code&gt;toEqual&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The test above will test different inputs towards our function and fail/pass based on its return.&lt;/p&gt;

&lt;p&gt;When testing the golden rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover all thinkable scenarios (not always possible) and create a test for it!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Jest is quite powerful so take a look into its &lt;a href="https://jestjs.io/docs/en/getting-started"&gt;documentation&lt;/a&gt; and explore it further more.&lt;/p&gt;

&lt;p&gt;If you have any questions please do ask!&lt;/p&gt;

&lt;h1&gt;
  
  
  Supertest
&lt;/h1&gt;

&lt;p&gt;With a fluent API, Supertest will help us test Node.js HTTP servers. Supertest is build upon Super-Agent Node.js library.&lt;/p&gt;

&lt;p&gt;To install Supertest run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -D supertest @types/supertest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to test our app, we are going to do some refactoring, create an file under &lt;code&gt;src/app.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&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;express&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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;routes&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="s2"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Boot express&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&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;Application&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;// Application routing&lt;/span&gt;
&lt;span class="nx"&gt;routes&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also we need/prefer to moved our routes definition into &lt;code&gt;src/routes.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Router&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;express&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PingController&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="s2"&gt;./controllers/PingController&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IndexController&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="s2"&gt;./controllers/IndexController&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;_routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IndexController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/ping&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PingController&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;_routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;route&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we can start organize our application easier. Go ahead and create following controllers, first, &lt;code&gt;src/controllers/IndexController.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Router&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IndexController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;IndexController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from Ornio AS!&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then &lt;code&gt;src/controllers/PingController.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Router&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PingController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;PingController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pong!&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally our &lt;code&gt;src/index.ts&lt;/code&gt; file is refactored to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app&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;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="c1"&gt;// Start server&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;`Server is listening 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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can go ahead and create a test for testing our &lt;code&gt;PingController&lt;/code&gt; using Supertest. &lt;code&gt;src/controller/PingController.test.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;request&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;supertest&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="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test PingController&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request /ping should return Pong!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&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;request&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/ping&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pong!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start with a normal Jest test by describing it and then we call &lt;code&gt;request(app)&lt;/code&gt; chained using ´get('/ping')´ which is the route and then finally we use &lt;code&gt;send()&lt;/code&gt; to send the request.&lt;/p&gt;

&lt;p&gt;When the request is sent and result is populated with the data we then checked if the status is 200 and the &lt;code&gt;body.data&lt;/code&gt; is equal to &lt;code&gt;Pong!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Supertest is quite powerful and can be used to send advance requests by modifying headers, generating/storing tokens etc. It supports all CRUD operations.&lt;/p&gt;

&lt;p&gt;I strongly recommend you to take a look on their &lt;a href="https://github.com/visionmedia/supertest#readme"&gt;documentation&lt;/a&gt; for more information and what Supertest can do.&lt;/p&gt;

&lt;p&gt;Thats all for now. Until next time happy coding :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Source code
&lt;/h1&gt;

&lt;p&gt;You can find the source code &lt;a href="https://github.com/ornio-no/post-nodejs-express-typescript-howto/tree/part-3"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Need help?
&lt;/h1&gt;

&lt;p&gt;Comment here or ping me on Twitter and I will gladly try to help you :)&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Docerizing an Node.js/Typescript (this) application (Part 4)&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>jest</category>
      <category>supertest</category>
      <category>node</category>
      <category>express</category>
    </item>
    <item>
      <title>Node.js (Express) with TypeScript, Eslint, Jest, Prettier and Husky - Part 2</title>
      <dc:creator>Flamur Mavraj</dc:creator>
      <pubDate>Sat, 08 Aug 2020 09:53:35 +0000</pubDate>
      <link>https://dev.to/ornio/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-2-5foi</link>
      <guid>https://dev.to/ornio/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-2-5foi</guid>
      <description>&lt;p&gt;On this part we are going to configure ESLint, Pettier and Husky.&lt;/p&gt;

&lt;p&gt;Head over to Medium to read the blog post:&lt;br&gt;
&lt;a href="https://medium.com/@oxodesign/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-2-f129188ce404"&gt;https://medium.com/@oxodesign/node-js-express-with-typescript-eslint-jest-prettier-and-husky-part-2-f129188ce404&lt;/a&gt;&lt;/p&gt;

</description>
      <category>eslint</category>
      <category>prettier</category>
      <category>husky</category>
      <category>node</category>
    </item>
  </channel>
</rss>
