<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hetav Desai]]></title><description><![CDATA[Software Engineer at **Unacademy**  •  Building Live Class Experience  •  UI/UX Design Enthusiast]]></description><link>https://blog.desaihetav.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 21 Apr 2026 19:24:24 GMT</lastBuildDate><atom:link href="https://blog.desaihetav.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[JavaScript Arrow Functions]]></title><description><![CDATA[Hello folks! In this article, we'll learn about Arrow Functions in JavaScript – what are they, how to use them, and their gotchas. If you're a beginner, I hope this helps you understand the concept well. And if you're already familiar with the concep...]]></description><link>https://blog.desaihetav.com/javascript-arrow-functions</link><guid isPermaLink="true">https://blog.desaihetav.com/javascript-arrow-functions</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ES6]]></category><dc:creator><![CDATA[Hetav Desai]]></dc:creator><pubDate>Tue, 15 Jun 2021 17:13:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1623777274523/1tuU3BrRG.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello folks! In this article, we'll learn about Arrow Functions in JavaScript – what are they, how to use them, and their gotchas. If you're a beginner, I hope this helps you understand the concept well. And if you're already familiar with the concept, you might want to go through its gotchas and when not to use them.</p>
<h1 id="heading-what-are-arrow-functions">What are Arrow Functions?</h1>
<p>Arrow functions were introduced with ES6 as a new way to write functions in JavaScript. The newer syntax made the code less verbose and more readable, as we don't need to write <code>function</code> and <code>return</code> keywords.</p>
<p>They are different from traditional functions in 2 aspects – syntax and scoping. The difference in syntax is clear and easy to pick, but the difference in scoping is rather subtle and it's important to understand the difference as it can break or alter the behaviour of the code.</p>
<h1 id="heading-syntax">Syntax</h1>
<p>Arrow functions can be written in different ways depending upon the number of parameters it accepts and the operation it performs.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// 1. One parameter, and a single return statement</span>
<span class="hljs-keyword">const</span> square = <span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> x*x;

<span class="hljs-comment">// 2. Multiple parameter, and a single return expression</span>
<span class="hljs-keyword">const</span> sum = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> x + y;

<span class="hljs-comment">// 3. Multiple statements in function expression</span>
<span class="hljs-keyword">const</span> sum = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Adding <span class="hljs-subst">${x}</span> and <span class="hljs-subst">${y}</span>`</span>);
    <span class="hljs-keyword">return</span> x + y;
}

<span class="hljs-comment">// 4. Returning an object</span>
<span class="hljs-keyword">const</span> sumAndDifference = <span class="hljs-function">(<span class="hljs-params">x, y</span>) =&gt;</span> ({ <span class="hljs-attr">sum</span>: x + y, <span class="hljs-attr">difference</span>: x - y });
</code></pre>
<h3 id="heading-quick-cheatsheet">Quick Cheatsheet</h3>
<ol>
<li><p>Optional parentheses in case of a single parameter</p>
</li>
<li><p>Must use parentheses in case of multiple parameters</p>
</li>
<li><p><code>return</code> keyword is not required for a single return expression in the function body</p>
</li>
<li><p><code>return</code> keyword required in case of multiple statements in the function</p>
</li>
<li><p>To return an object notation, wrap it with parentheses</p>
</li>
<li><p>Rest operator, default parameters, and destructuring of parameters work normally</p>
</li>
</ol>
<h1 id="heading-when-to-use-arrow-functions">When to use Arrow Functions?</h1>
<h3 id="heading-for-passing-anonymous-callback-functions-to-array-methods">For passing anonymous callback functions to array methods</h3>
<p>The array methods like <code>.map()</code>, <code>.filter()</code>, <code>.reduce()</code>, etc. can look really concise and clean when arrow functions are used to pass the callback functions.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> numbers = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];

<span class="hljs-keyword">const</span> sum = numbers.reduce(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a + b, <span class="hljs-number">0</span>);
</code></pre>
<h3 id="heading-promise-chaining">Promise Chaining</h3>
<p>The promise chaining can look very confusing with repetitive <code>function</code> and <code>return</code> keywords. By using arrow functions, we can write promise chains with minimal code and a more readable manner.</p>
<pre><code class="lang-javascript">fetch(URL)
.then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json())
.then(<span class="hljs-function"><span class="hljs-params">json</span> =&gt;</span> json.data)
.then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> data.map(<span class="hljs-function"><span class="hljs-params">dataItem</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(dataItem)))
</code></pre>
<h3 id="heading-callback-functions">Callback Functions</h3>
<p>In JavaScript, we write a lot of callback functions, and using arrow functions to do that can make it really clean</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I'll get logged first"</span>);
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"I'll get logged later"</span>);
    })
});
</code></pre>
<h1 id="heading-gotchas">Gotchas</h1>
<h2 id="heading-this-keyword-is-arrow-function-is-inherited-from-the-scope-in-which-it-is-defined"><code>this</code> keyword is arrow function is inherited from the scope in which it is defined</h2>
<h3 id="heading-this-restricts-the-use-of-arrow-functions-as-object-methods">This restricts the use of arrow functions as object methods.</h3>
<p>An object method defined using traditional function creates its own scope and <code>this</code> refers to the object which has the method stored as its property.</p>
<p>Since arrow functions use lexical scoping for <code>this</code>, if an object method is defined using arrow functions, <code>this</code> would not refer to the object which has this method stored as a property, instead, it would refer to its parent scope.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> obj = {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Hetav Desai"</span>,
    <span class="hljs-attr">printWithTraditionalFunction</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.name);
    }
    <span class="hljs-attr">printWithArrowFunction</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.name)
}

obj.printWithTraditionalFunction();
<span class="hljs-comment">// Hetav Desai</span>

obj.printWithArrowFunction();
<span class="hljs-comment">// undefined</span>
</code></pre>
<h3 id="heading-callback-functions-and-this">Callback functions and <code>this</code></h3>
<p>You should also be careful while using arrow functions for defining callbacks that require <code>this</code>. Example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Callback using arrow function</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">counter1</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">this</span>.count = <span class="hljs-number">0</span>;
  <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.count++
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.count);
  }, <span class="hljs-number">1000</span>)
}
counter1();

<span class="hljs-comment">// Callback using traditional function</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">counter2</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">this</span>.count = <span class="hljs-number">0</span>;
  <span class="hljs-built_in">setInterval</span>(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">this</span>.count++
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.count);
  }, <span class="hljs-number">1000</span>)
}
counter2();
</code></pre>
<p>In the above example, <code>this</code> keyword in the first function refers to the function <code>counter1</code> and hence variable <code>count</code> can be accessed inside callback function using <code>this.count</code>, and the function increments a number every second and prints it.</p>
<p>While in the case of function <code>counter2</code>, <code>this</code> keyword inside callback function refers to its own scope and not that of <code>counter2</code>. Hence, it cannot access <code>count</code> variable and prints <code>NaN</code> every second,</p>
<h2 id="heading-unlike-traditional-functions-arrow-functions-are-not-hoisted">Unlike traditional functions, arrow functions are not hoisted</h2>
<p>Because of this, you cannot call them before they are declared.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Using Normal Function</span>
printWithTraditionalFunction(<span class="hljs-string">"Hetav"</span>) <span class="hljs-comment">// prints Hetav</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printWithTraditionalFunction</span>(<span class="hljs-params">name</span>) </span>{
    <span class="hljs-built_in">console</span>.log(name)
}

<span class="hljs-comment">// Using Arrow Function</span>
printWithTraditionalFunction(<span class="hljs-string">"Hetav"</span>) <span class="hljs-comment">// throws ReferenceError</span>
<span class="hljs-keyword">const</span> printWithArrowFunction = <span class="hljs-function"><span class="hljs-params">name</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(name);
</code></pre>
<h3 id="heading-binding-arguments-object-not-available-for-arrow-functions">Binding <code>arguments</code> object not available for arrow functions</h3>
<p><code>arguments</code> is an Array-like object accessible inside functions that contain the values of the arguments passed to that function. But it is not available for arrow functions.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">something</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">arguments</span>.length); <span class="hljs-comment">// prints the number of arguments passed</span>
}
something(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>) <span class="hljs-comment">// prints 3</span>

<span class="hljs-keyword">const</span> something = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">arguments</span>.length); <span class="hljs-comment">// prints the number of arguments passed</span>
}
something(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>) <span class="hljs-comment">// throws Reference Error: arguments not found</span>
</code></pre>
<p>Now that we cannot access <code>arguments</code> in arrow functions, does it mean that we are forced to use traditional functions? Nope, not at all.</p>
<p><strong>Rest parameters of ES6 to the rescue</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> something = <span class="hljs-function">(<span class="hljs-params">..args</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(args.length); <span class="hljs-comment">// prints the number of arguments passed</span>
}
something(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>) <span class="hljs-comment">// prints 3</span>
</code></pre>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In this article, we saw that JavaScript arrow functions are really awesome and have minimal and readable syntax which makes it very easy for developers to write clean code. However, there are certain scenarios where using traditional functions is recommended. Except that, I'd strongly suggest using arrow functions everywhere.</p>
<p>Thank you for reading the blog. Do drop your feedback in the comments below and if you liked it, share it with your developer friends who might find it useful too. If you want to have any discussion around this topic, feel free to reach out to me on <a target="_blank" href="https://twitter.com/desaihetav">Twitter</a></p>
]]></content:encoded></item><item><title><![CDATA[Using GraphQL with Axios and Redux]]></title><description><![CDATA[Hello folks, in this article I'll be showing you how you can use GraphQL with Axios and Redux, along with error handling. This is not a beginner tutorial. Hence a basic understanding of how GraphQL, Axios, and Redux work will be helpful. And if you a...]]></description><link>https://blog.desaihetav.com/using-graphql-with-axios-and-redux</link><guid isPermaLink="true">https://blog.desaihetav.com/using-graphql-with-axios-and-redux</guid><category><![CDATA[React]]></category><category><![CDATA[GraphQL]]></category><category><![CDATA[Redux]]></category><category><![CDATA[axios]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Hetav Desai]]></dc:creator><pubDate>Mon, 14 Jun 2021 14:22:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1623680410899/Zlqw9n4yN.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello folks, in this article I'll be showing you how you can use GraphQL with Axios and Redux, along with error handling. This is not a beginner tutorial. Hence a basic understanding of how GraphQL, Axios, and Redux work will be helpful. And if you are familiar with these technologies, let me tell you that this combination isn't as difficult as you might be wondering.</p>
<h2 id="heading-a-not-so-little-context-as-to-why-such-a-different-combination">A not-so-little context as to why such a different combination</h2>
<p>Recently I started working on a project with a primary motive to understand and practice redux-toolkit well. I've been using REST APIs for a while, and now I wanted to try my hands on GraphQL too. So I kicked off this project by setting up CRA with redux-toolkit for the frontend and Hasura for the backend.</p>
<p>Now that these two things were in place, I started exploring different GraphQL client libraries that I could use and from most resources, I found the following options – <code>apollo client</code>, <code>react-query</code> and <code>urql</code>. I soon realized that these libraries won't work for me for the following reasons:</p>
<ol>
<li><p>These libraries provide hooks like <code>useQuery</code> and <code>useMutation</code> for accessing GraphQL APIs</p>
</li>
<li><p>I was using <code>createAsyncThunk</code> from <code>redux-toolkit</code> for state management</p>
</li>
<li><p>The hooks provided by libraries won't work with <code>createAsyncThunk</code> as it is not a React component</p>
</li>
</ol>
<p>After further digging, I found a client library called <code>graphql-request</code> which would let me access GraphQL APIs without using hooks. But the issue with this one was that I could not set default global headers and I would need to create multiple instances of <code>GraphQLClient</code>, which seemed rather wasteful.</p>
<p>All of this got me wondering, can't I just use <code>axios</code> for GraphQL? And the answer is YES.</p>
<h2 id="heading-using-axios-for-accessing-graphql-api">Using Axios for accessing GraphQL API</h2>
<p>Axios is an HTTP client library, and hence it can be used to access GraphQL APIs as they're served over HTTP. We'll see how we can do that with a small example.</p>
<p>Let's suppose that we have a huge database of Users and we want to fetch details of a single user based on <strong>userId</strong>. The GraphQL query for this operation will be:</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">query</span> (<span class="hljs-variable">$userId</span>: uuid!) {
  users(<span class="hljs-symbol">where:</span> {<span class="hljs-symbol">id:</span> {<span class="hljs-symbol">_eq:</span> <span class="hljs-variable">$userId</span>}}) {
    name
    email
  }
}
</code></pre>
<p>The above query will take <code>userId</code> as a <strong>required</strong> variable of <strong>type</strong> <code>uuid</code> and return the name and email of the user whose <code>userId</code> matches the passed <code>userId</code>.</p>
<p>Let's assume the API endpoint to be <code>https://api.somelink.com/graphql</code>. We can execute our query using axios as mentioned below.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">"https://api.somelink.com/graphql"</span>, {
  <span class="hljs-attr">query</span>: <span class="hljs-string">`
    query ($userId: uuid!) {
      users(where: {id: {_eq: $userId}}) {
        name
        email
      }
    }
  `</span>,
  <span class="hljs-attr">variables</span>: {
    <span class="hljs-attr">userId</span>: <span class="hljs-string">"user-12345"</span>,
  },
});
</code></pre>
<p><strong>One thing to pay attention to is that no matter if we're doing a query or a mutation, we'll always make a POST call as we need to pass query and variables as request body.</strong></p>
<p>Yes, that's it.</p>
<h2 id="heading-lets-combine-this-with-redux">Let's combine this with Redux</h2>
<p>Let's consider a scenario where we have a Profile component to display the name, and email of a user. When this component loads, we want to fetch the details of a user from the API and render it on the screen and maintain the state using redux-toolkit. To do this, we'll follow the below steps:</p>
<h3 id="heading-1-write-state-management-logic-in-reducer">1. Write state management logic in reducer</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// userSlice.js</span>

<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> { createSlice, createAsyncThunk } <span class="hljs-keyword">from</span> <span class="hljs-string">"@reduxjs/toolkit"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> loadUser = createAsyncThunk(
  <span class="hljs-string">"post/loadUser"</span>,
  <span class="hljs-keyword">async</span> ({ userId }) =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">"https://api.somelink.com/graphql"</span>, {
      <span class="hljs-attr">query</span>: <span class="hljs-string">`
        query ($userId: uuid!) {
          users(where: {id: {_eq: $userId}}) {
            name
            email
          }
        }
      `</span>,
      <span class="hljs-attr">variables</span>: {
        <span class="hljs-attr">userId</span>: <span class="hljs-string">"user-12345"</span>,
      },
    });
    <span class="hljs-keyword">return</span> response;
  }
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> userSlice = createSlice({
  <span class="hljs-attr">name</span>: <span class="hljs-string">"user"</span>,
  <span class="hljs-attr">initialState</span>: {
    <span class="hljs-attr">status</span>: <span class="hljs-string">"idle"</span>,
    <span class="hljs-attr">user</span>: {},
    <span class="hljs-attr">errorMessage</span>: <span class="hljs-string">""</span>,
  },
  <span class="hljs-attr">reducers</span>: {},
  <span class="hljs-attr">extraReducers</span>: {
    [loadUser.pending]: <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
      state.status = <span class="hljs-string">"loading"</span>;
    },
    [loadUser.fulfilled]: <span class="hljs-function">(<span class="hljs-params">state, { payload }</span>) =&gt;</span> {
      state.user = payload.data.data.user;
      state.status = <span class="hljs-string">"fulfilled"</span>;
    },
    [loadUser.rejected]: <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
      state.status = <span class="hljs-string">"error"</span>;
      state.errorMessage = <span class="hljs-string">"Could not fetch data. Please refresh to try again."</span>
    },
  },
});
</code></pre>
<p>The <code>loadUser</code> function will be called when dispatched from React component. It'll make a network call to fetch required user from the database.</p>
<p>Based on the state of Promise of network call, the corresponding functions in the <code>extraReducers</code> will be executed.</p>
<h3 id="heading-2-create-a-profile-component">2. Create a Profile Component</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// ProfileComponent.jsx</span>

<span class="hljs-keyword">import</span> { useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useDispatch, useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { loadUsers } <span class="hljs-keyword">from</span> <span class="hljs-string">'./postSlice.js'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ProfileComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> dispatch = useDispatch();
  <span class="hljs-keyword">const</span> { user, status, errorMessage } = useSelector(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> state.user);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    status === <span class="hljs-string">"idle"</span> &amp;&amp; dispatch(loadUser());
  }, [])

  <span class="hljs-keyword">return</span> status === <span class="hljs-string">"loading"</span> &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> status === <span class="hljs-string">"error"</span> &amp;&amp; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{errorMessage}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{user.email}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{user.contact_number}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>The <code>ProfileComponent</code> consumes the redux state via <code>useSelector</code> and fires a dispatch action <code>loadUser()</code> when it is loaded.</p>
<p>It'll show <code>Loading...</code> while the user data is being fetched. Once the data is received, it'll render it on the screen.</p>
<h2 id="heading-error-handling">Error Handling</h2>
<p>In case of error, we would expect that, the <code>[loadUser.rejected]</code> part of <code>extraReducer</code> will be executed and the error will be handled.</p>
<p>But the catch here is that GraphQL doesn't respond with error status codes like REST and hence all the responses end up with status 200.</p>
<p>Here's is the format in which GraphQL API would send response in case of success and error.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/*
GraphQL API Response (Success)
It responds with data object and
it is enclosed in data field of axios response
*/</span>
{
  <span class="hljs-attr">config</span>: {...},
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">data</span>: {
      <span class="hljs-attr">users</span>: [{
        <span class="hljs-attr">name</span>: <span class="hljs-string">"John Doe"</span>,
        <span class="hljs-attr">email</span>: <span class="hljs-string">"johndoe@mail.com"</span>
      }],
    },
  },
  <span class="hljs-attr">headers</span>: {...},
  <span class="hljs-attr">request</span>: {...},
  <span class="hljs-attr">status</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">statusText</span>: <span class="hljs-string">"OK"</span>
}

<span class="hljs-comment">/*
GraphQL API Response (Error)
It responds with array of error objects and
it is enclosed in data field of axios response
*/</span>
{
  <span class="hljs-attr">config</span>: {...},
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">errors</span>: [{
      <span class="hljs-string">"extensions"</span>: {
        <span class="hljs-string">"path"</span>: <span class="hljs-string">"$.selectionSet.users.selectionSet.contact"</span>,
        <span class="hljs-string">"code"</span>: <span class="hljs-string">"validation-failed"</span>
      },
      <span class="hljs-string">"message"</span>: <span class="hljs-string">"field \"contact\" not found in type: 'users'"</span>
    }]
  },
  <span class="hljs-attr">headers</span>: {...},
  <span class="hljs-attr">request</span>: {...},
  <span class="hljs-attr">status</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">statusText</span>: <span class="hljs-string">"OK"</span>
}
</code></pre>
<p>Now because of this format of response, even in case of error, <code>[loadUser.rejected]</code> in <code>extraReducers</code> doesn't get executed, instead <code>[loadUser.fulfilled]</code> gets executed. So we need to do some error handling manually.</p>
<p>To handle this, at the end of <code>createAsyncThunk</code> we'll check the contents of the response to see if we're getting data object or array of error objects. If we get array of error objects, we'll explicitly throw an <code>Error</code> or else we'll return the response as it is.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> loadUser = createAsyncThunk(
  <span class="hljs-string">"post/loadUser"</span>,
  <span class="hljs-keyword">async</span> ({ userId }) =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">"https://api.somelink.com/graphql"</span>, {
      <span class="hljs-attr">query</span>: <span class="hljs-string">`
        query ($userId: uuid!) {
          users(where: {id: {_eq: $userId}}) {
            name
            email
          }
        }
      `</span>,
      <span class="hljs-attr">variables</span>: {
        <span class="hljs-attr">userId</span>: <span class="hljs-string">"user-12345"</span>,
      },
    });
    <span class="hljs-keyword">if</span>(response.data.errors) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Could not fetch data. Please refresh to try again."</span>)
    }
    <span class="hljs-keyword">return</span> response.data.data;
  }
);
</code></pre>
<p>We can catch this in the <code>extraReducers</code> as below</p>
<pre><code class="lang-javascript">[loadUser.rejected]: <span class="hljs-function">(<span class="hljs-params">state, action</span>) =&gt;</span> {
  state.status = <span class="hljs-string">"error"</span>;
  state.errorMessage = action.error.message;
},
</code></pre>
<p>That's how we use GraphQL with Axios and Redux</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog, we learned how to use GraphQL with Axios and Redux and how to handle errors in this process.</p>
<p>Now the question is – Is it recommended to use this combination in apps? Probably not. I did it as I was creating a project for learning purposes.</p>
<p>For a production app, using one of the well-known libraries like Apollo Client, urql, etc. would be a better choice. But in case you're using REST API across the project, and need to use GraphQL API in one or two places, then this method can come in very handy.</p>
<p>Thank you for reading the blog. Do drop your feedback in the comments below and if you liked it, share it with your developer friends who might find it useful too. If you want to have any discussion around this topic, feel free to reach out to me on <a target="_blank" href="https://twitter.com/desaihetav">Twitter</a></p>
]]></content:encoded></item><item><title><![CDATA[Why Are React Hooks Required?]]></title><description><![CDATA[If you are new to Web Development or React in particular, you might have heard this buzz word "React Hooks" a lot and might be finding it overwhelming too. You may be having questions like – "Should I learn it? Is it important? Is it even required fo...]]></description><link>https://blog.desaihetav.com/why-are-react-hooks-required</link><guid isPermaLink="true">https://blog.desaihetav.com/why-are-react-hooks-required</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><dc:creator><![CDATA[Hetav Desai]]></dc:creator><pubDate>Sat, 16 Jan 2021 09:18:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610727518824/-AU19XTCH.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are new to Web Development or React in particular, you might have heard this buzz word "React Hooks" a lot and might be finding it overwhelming too. You may be having questions like – "Should I learn it? Is it important? Is it even required for a beginner like me?".</p>
<p>I cannot straight away answer your questions, but I can help you understand why do React Hooks exist and what motivated their introduction to React by the React Team. This understanding will help you decide whether to learn React Hooks or not.</p>
<h2 id="lets-get-started">Let's get started</h2>
<p>Just so that we don't get overwhelmed with all the things that hooks have to offer, let's first define our goal for this article and we'll stick to it.</p>
<blockquote>
<p>To answer why are React Hooks required, we will need to understand one thing: <strong>What problems do React Hooks solve?</strong></p>
</blockquote>
<h2 id="background">Background</h2>
<p>To get a little context, let's see how React has evolved over the years. Initially, when React was released, there was no concept of class in JavaScript and hence it had to be handled by React. Back then, the React Components were created using <code>React.createClass</code> API as shown in the code snippet below.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> ExampleComponent = React.createClass({
  getInitialState () {
    <span class="hljs-keyword">return</span> {
        <span class="hljs-comment">// ...</span>
    }
  },
  componentDidMount () {
    <span class="hljs-comment">// setup</span>
    <span class="hljs-comment">// add listener for feature 1</span>
    <span class="hljs-comment">// add listener for feature 2</span>
    <span class="hljs-comment">// and so on...</span>
  },
  componentDidUpdate () {
    <span class="hljs-comment">// logic to update state</span>
  },
  componentWillUnmount () {
    <span class="hljs-comment">// clean up</span>
    <span class="hljs-comment">// remove listener for feature 1</span>
    <span class="hljs-comment">// remove listener for feature 2</span>
    <span class="hljs-comment">// and so on...</span>
  },

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="hljs-comment">// ...</span>
    )
  }
})
</code></pre>
<h3 id="post-es6-release">Post ES6 release</h3>
<p>With the release of ES6, the <code>class</code> keyword was introduced in JavaScript and it was a new way to create classes in JavaScript. Later, React deprecated the <code>createClass</code> API and moved to <code>React.Component</code> API. Now we could create React Components using JavaScript native way of creating classes, as shown in the snippet below.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ExampleComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-built_in">super</span>(props);

    <span class="hljs-built_in">this</span>.state = {
      <span class="hljs-comment">// ...</span>
    };

    <span class="hljs-built_in">this</span>.exampleFunction = <span class="hljs-built_in">this</span>.exampleFunction.bind(<span class="hljs-built_in">this</span>);
  }
  componentDidMount() {
    <span class="hljs-comment">// setup</span>
    <span class="hljs-comment">// add listener for feature 1</span>
    <span class="hljs-comment">// add listener for feature 2</span>
    <span class="hljs-comment">// and so on...</span>
  }

  componentDidUpdate() {
    <span class="hljs-comment">// logic to update state</span>
  }

  componentWillUnmount () {
    <span class="hljs-comment">// clean up</span>
    <span class="hljs-comment">// remove listener for feature 1</span>
    <span class="hljs-comment">// remove listener for feature 2</span>
    <span class="hljs-comment">// and so on...</span>
  },

  exampleFunction() {
    <span class="hljs-comment">//...</span>

    <span class="hljs-built_in">this</span>.setState({
      <span class="hljs-comment">// ...</span>
    });
  }

  render() {
    <span class="hljs-comment">// ...</span>
  }
}
</code></pre>
<p>With this change, React got better, but it still had some tradeoffs. Every time while creating a component, it was compulsory to use the constructor and call <code>super(props)</code> and also <code>.bind</code> every function using <code>.this</code> keyword in the constructor.</p>
<p>Now, these weren't too big of an issue, and also these weren't React issues because this is how classes worked in JavaScript. But still, there had to be some efficient way to overcome this problem.</p>
<p>Later, something called <code>Class</code> Fields were released, which allowed us to directly add properties to the class, without having to use constructor and we no longer needed to <code>.bind</code> any methods in the constructor as we could use arrow functions to create methods in a class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span> <span class="hljs-title">Component</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
    state = {
        <span class="hljs-comment">// ...</span>
    }

    exampleFunction = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">// ...</span>
    }
}
</code></pre>
<h3 id="react-functional-components">React Functional Components</h3>
<p>Then with Functional Components, there was a simpler way to create components that did not require any state management or lifecycle methods. Initially, Functional Components were stateless components. They would take in props and simply render a UI, no other complexity was involved.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExampleComponent</span>(<span class="hljs-params">{ props }</span>) </span>{
  <span class="hljs-comment">// ...</span>
  <span class="hljs-keyword">return</span>(
      <span class="hljs-comment">// ...</span>
  );
}
</code></pre>
<p>Now, this was the stage, just before hooks were introduced. At this point, there was a considerable scope of improvement in the following areas:</p>
<ul>
<li><p>State Management</p>
<ul>
<li>Even the simplest state management requirements made it compulsory for us to use Class Components instead of Functional Components and it just got messy with complex state management.</li>
</ul>
</li>
<li><p>Lifecycle Methods</p>
<ul>
<li>With the use of lifecycle methods, the logic that is related to the component was spread across the component. For instance, in the code snippets above, the actual logic lied in the <code>exampleFunction</code>, while the logic of when to call <code>exampleFunction</code> was contained in <code>componentDidMount</code> and <code>componentDidUpdate</code> methods.</li>
<li>In addition to this, the lifecycle methods could also contain several other unrelated logic that needs to be executed at a particular lifecycle stage.</li>
</ul>
</li>
<li><p>Non Visual Logic was not Reusable</p>
<ul>
<li>Due to the logic of the component being spread across the component and React Components, being a combination of logic and UI, it made the reusability of non-visual logic (i.e. logic without UI) very complex.</li>
</ul>
</li>
</ul>
<p>These were the exact problems that motivated the introduction of React Hooks.</p>
<h2 id="react-hooks">React Hooks</h2>
<p>The React team introduced React Hooks to the world at React Conf in late October 2018. In early February 2019, they finally came in React v16.8.0.</p>
<p>React Hooks enables you to use state and other React features, without writing a class, in functional components. It gives combined advantage of Functional Components clean code and Class Components powerful features. And all this is possible because React Hooks are just regular JavaScript functions.</p>
<h3 id="state-management">State Management</h3>
<p>React Hooks provide a new way to add and manage state in functional components using the <code>useState</code> hook. The useState method takes in the initial value of a state variable as the only argument and it returns an array of two items, the first being the state variable and the second being a function to update that state variable.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-comment">// count is state variable</span>
  <span class="hljs-comment">// setCount is method to update state variable count</span>
  <span class="hljs-comment">// initial value of count will be 0, as passed in useState</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="lifecycle-methods">Lifecycle Methods</h3>
<p>With Hooks, React introduces a new way to connect logic and its trigger conditions. Instead of writing all the unrelated logic in a block of a lifecycle method that needs to be executed at a particular stage in the lifecycle, we can now write any logic independently and pass in the trigger conditions with the help of the <code>useEffect</code> hook.</p>
<p><code>useEffect</code> lets us perform side effects inside functional components. It takes two arguments, the first being a function and the second being an optional array. The function defines which side effect is to be run and the optional array defines when should the effect be triggered or re-run. The effect is triggered whenever the value of the variables passed in the array changes.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">document</span>.title = <span class="hljs-string">`You clicked <span class="hljs-subst">${count}</span> times`</span>;
  });

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="reusable-non-visual-logic">Reusable Non Visual Logic</h3>
<p>When it comes to sharing non-visual logic across components, there is no inbuilt hook like useState or useEffect which can directly take care of it. But there is a flexibility of creating <strong>our custom hooks</strong>, using the different inbuilt hooks as required. This lets us extract the logic out of the component and make it reusable across components.</p>
<p>An example of such logic is handling Authentication State. In apps with authentication, there may be several functionalities where you need to check for authentication and only allow logged-in users to access that functionality. In this scenario, you should not be required to write logic to handle the authentication state in multiple components. You can write the logic once inside a custom hook and access it across components.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useState, useEffect, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useAuthListener</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [user, setUser] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// setup – add auth state listener</span>
    <span class="hljs-comment">// logic to handle auth state change</span>
    <span class="hljs-comment">// clean up – remove auth state listener</span>
  }, []);

  <span class="hljs-keyword">return</span> { user };
}
</code></pre>
<h1 id="conclusion">Conclusion</h1>
<p>I think, by now, you would have got a fair idea of how Hooks has enabled us to have better <strong>state management</strong>, <strong>concentrated effect logic</strong>, and <strong>reusable non-visual logic</strong>.</p>
<p>Since the scope of this article is to understand why are React Hooks required, I've taken the simplest examples of hooks and not gone into a detailed explanation of how each of them works. While there is a lot more about hooks that make them powerful and there are many different ways in which we can use hooks, the content covered in this article is enough to answer our primary question: What problems do hooks solve, and why are they required?</p>
<p>In upcoming posts, I'll be writing in detail about different hooks, how they work and how can they be used in our projects.</p>
<hr />
<p>Thank you very much for reading this article. I hope you found it useful and if you did, please do share it with your friends or anyone who may find this interesting.</p>
<p>Connect with me on <a target="_blank" href="https://twitter.com/desaihetav">Twitter</a> and <a target="_blank" href="https://linkedin.com/in/desaihetav">LinkedIn</a> to get updates on my new blog posts.</p>
]]></content:encoded></item><item><title><![CDATA[FAANG/M is not what you think it is!]]></title><description><![CDATA[What does FAANG/M stand for?
Facebook, Apple, Amazon, Netflix, Google and Microsoft are the technology giants that comprise the popular acronym FAANG or FAAMG or FAANGM.
The General Perception
Most people in the tech community have a perception that ...]]></description><link>https://blog.desaihetav.com/faangm-is-not-what-you-think-it-is</link><guid isPermaLink="true">https://blog.desaihetav.com/faangm-is-not-what-you-think-it-is</guid><dc:creator><![CDATA[Hetav Desai]]></dc:creator><pubDate>Tue, 15 Dec 2020 13:57:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1608134756395/9JHZ94cc8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="what-does-faangm-stand-for">What does FAANG/M stand for?</h3>
<p><strong>F</strong>acebook, <strong>A</strong>pple, <strong>A</strong>mazon, <strong>N</strong>etflix, <strong>G</strong>oogle and <strong>M</strong>icrosoft are the technology giants that comprise the popular acronym <strong>FAANG</strong> or <strong>FAAMG</strong> or <strong>FAANGM</strong>.</p>
<h3 id="the-general-perception">The General Perception</h3>
<p>Most people in the tech community have a perception that these are <em>"the best employers with good pay and great perks"</em> and hence every fresher coming out of college dreams of joining one of these FAANGM companies. If you're one of those people who think this is true, then let me break it to you that this acronym has nothing to do with tech, nothing at all.</p>
<h3 id="so-what-does-it-really-mean">So what does it really mean?</h3>
<p>The term comes from stock market point of view and was coined by Jim Cramer, the television host of CNBC's Mad Money, in 2013, who thought these companies were totally dominant in their markets and had grown exponentially in the stock markets during that time.</p>
<p>Originally, the term FANG was used, without Apple being included in it. Later, in 2017, when Apple's stock had made larger gains, it was added and the term became FAANG.</p>
<h3 id="why-microsoft-isisnt-included">Why Microsoft is/isn't included?</h3>
<p>Microsoft wasn't performing anywhere near to these companies and hence it hadn't made it to this acronym. However, after the appointment of Satya Nadella as the CEO of Microsoft in 2014, the company showed massive growth and its stock almost quadrupled from 2014 to 2019. This compelled the stock market experts to squeeze in Microsoft in the acronym. Later in 2019, Goldman Sachs came up with FAAMG, replacing Netflix with Microsoft. It chose to do so because of Netflix's relatively small market capitalisation compared to the others. Also, FAAMG is somewhat more focused on tech companies as Netflix is considered to be a consumer services and media company.</p>
<h3 id="conclusion">Conclusion</h3>
<p>FAANG or FAAMG might be thought of as best employers to work for but that wasn’t the case when it was coined, and it isn’t the case today either.</p>
<p>Thank you very much for reading this article and if you found it useful, please do share it with your friends or anyone who may find this interesting.</p>
]]></content:encoded></item><item><title><![CDATA[COVID-19 Dashboard in Python using Streamlit]]></title><description><![CDATA[The Coronavirus outbreak has brought the whole world to a standstill. This presents to us an opportunity to do things that we have always wanted to but couldn’t just because of lack of time. With my interests in computers, I have always wanted to cre...]]></description><link>https://blog.desaihetav.com/covid-19-dashboard-in-python-using-streamlit</link><guid isPermaLink="true">https://blog.desaihetav.com/covid-19-dashboard-in-python-using-streamlit</guid><category><![CDATA[Data Science]]></category><category><![CDATA[data analysis]]></category><category><![CDATA[#data visualisation]]></category><dc:creator><![CDATA[Hetav Desai]]></dc:creator><pubDate>Sun, 07 Jun 2020 20:23:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1601065879070/J6fFR4PIy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Coronavirus outbreak has brought the whole world to a standstill. This presents to us an opportunity to do things that we have always wanted to but couldn’t just because of lack of time. With my interests in computers, I have always wanted to create something which is actually useful in real life and which can create an impact. So, during this lockdown period, as I am learning Data Analysis and Machine Learning, I thought of putting my skills to practice and develop a dashboard which can help create awareness among the people, help them understand the intensity of this pandemic and inspire them to stay at home and help the world come out of this miserable times.</p>
<p>In this blog, I’ll take you through the complete process that I have followed while creating the dashboard.</p>
<blockquote>
<p>To have a look at the end result before jumping in the process, checkout the link here: <a target="_blank" href="https://desaihetav-streamlit-covid-19-dashboard-app-4jgtjw.streamlit.app/">COVID-19 Dashboard by Hetav Desai</a></p>
</blockquote>
<h2 id="heading-steps">Steps</h2>
<ol>
<li><p>Collect data. Use the data source that is reliable and frequently updated with latest numbers.</p>
</li>
<li><p>Process the data. Structure the data as required for the analysis.</p>
</li>
<li><p>Clean the data. Remove unnecessary, duplicate and outlier data. Basically any kind of data that has the potential to generate errors in analysis.</p>
</li>
<li><p>Analyse the data. Create meaningful visualisations out of the data.</p>
</li>
<li><p>Present interpretations of analysis in an easily readable and understandable manner.</p>
</li>
</ol>
<h2 id="heading-packages-used">Packages Used</h2>
<ol>
<li><p>Pandas — to analyse and manipulate data</p>
</li>
<li><p>NumPy — to work with arrays and perform basic mathematical operations</p>
</li>
<li><p>Plotly — to create visualisations</p>
</li>
<li><p>Streamlit — to add interactivity and present visualisations in dashboard format</p>
</li>
</ol>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> plotly.graph_objects <span class="hljs-keyword">as</span> go
<span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st
</code></pre>
<h2 id="heading-data-collection">Data Collection</h2>
<p>I have used the dataset published by CSSE, John Hopkins University on their GIT repository which is regularly updated. Here’s the <a target="_blank" href="https://github.com/CSSEGISandData/COVID-19">link</a>.</p>
<p>The <code>read_csv()</code> function from pandas library is used to read <code>.csv</code> data into a data frame.</p>
<pre><code class="lang-python">death_df = pd.read_csv(<span class="hljs-string">'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv'</span>)
confirmed_df = pd.read_csv(<span class="hljs-string">'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv'</span>)
recovered_df = pd.read_csv(<span class="hljs-string">'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv'</span>)
country_df = pd.read_csv(<span class="hljs-string">'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/web-data/data/cases_country.csv'</span>)
delta_df = pd.read_csv(<span class="hljs-string">'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/web-data/data/cases_time.csv'</span>, parse_dates=[<span class="hljs-string">'Last_Update'</span>])
</code></pre>
<p>Let’s have a look at the structure of these data frames. confirmed_df.head() gives the following output.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601065760304/jgKJsB2e3.png" alt="Dataframe1" /></p>
<p>The data frame consists columns from 22nd Jan to current date. The structure of other three data frames is similar to this.</p>
<h2 id="heading-data-processing-and-cleaning">Data Processing and Cleaning</h2>
<p>Let’s convert all the column names to lowercase as it makes it easy to access them. Also, we will convert <code>Province/State</code> to <code>state</code> and <code>Country/Region</code> to <code>country</code> for better accessibility.</p>
<pre><code class="lang-python">country_df.columns = map(str.lower, country_df.columns)
confirmed_df.columns = map(str.lower, confirmed_df.columns)
death_df.columns = map(str.lower, death_df.columns)
recovered_df.columns = map(str.lower, recovered_df.columns)
delta_df.columns = map(str.lower, delta_df.columns)
confirmed_df = confirmed_df.rename(columns={<span class="hljs-string">'province/state'</span>: <span class="hljs-string">'state'</span>, <span class="hljs-string">'country/region'</span>: <span class="hljs-string">'country'</span>, <span class="hljs-string">'lat'</span>: <span class="hljs-string">'lat'</span>, <span class="hljs-string">'long'</span>: <span class="hljs-string">'lon'</span>})
recovered_df = recovered_df.rename(columns={<span class="hljs-string">'province/state'</span>: <span class="hljs-string">'state'</span>, <span class="hljs-string">'country/region'</span>: <span class="hljs-string">'country'</span>})
death_df = death_df.rename(columns={<span class="hljs-string">'province/state'</span>: <span class="hljs-string">'state'</span>, <span class="hljs-string">'country/region'</span>: <span class="hljs-string">'country'</span>})
country_df = country_df.rename(columns={<span class="hljs-string">'country_region'</span>: <span class="hljs-string">'country'</span>})
delta_df = delta_df.rename(columns={<span class="hljs-string">'last_update'</span>: <span class="hljs-string">'date'</span>, <span class="hljs-string">'country_region'</span>: <span class="hljs-string">'country_name'</span>})
</code></pre>
<h2 id="heading-data-analysis">Data Analysis</h2>
<p>Now that we have a frequently updated data from a reliable source, converted to a format that easily accessible, let’s get into the analysis of this data.</p>
<h3 id="heading-calculating-total-confirmed-death-and-recovered-cases-across-the-world">Calculating total Confirmed, Death and Recovered Cases across the World</h3>
<p>The <code>country_df</code> has columns for confirmed, death and recovered cases for each country. Taking the sum of respective cases for each country(i.e. sum of values in respective columns), gives us the total number of respective cases across the world.</p>
<pre><code class="lang-python">confirmed_total = int(country_df[<span class="hljs-string">'confirmed'</span>].sum())
deaths_total = int(country_df[<span class="hljs-string">'deaths'</span>].sum())
recovered_total = int(country_df[<span class="hljs-string">'recovered'</span>].sum())
</code></pre>
<h3 id="heading-calculating-current-day-increasedecrease-in-respective-cases">Calculating Current Day Increase/Decrease in Respective Cases</h3>
<p>The sum of values in last column of <code>confirmed_df</code>, <code>death_df</code> and <code>recovered_df</code> gives us the total number of respective cases for current day.</p>
<pre><code class="lang-python">confirmed_df[confirmed_df.columns[<span class="hljs-number">-1</span>]].sum()
death_df[death_df.columns[<span class="hljs-number">-1</span>]].sum()
recovered_df[recovered_df.columns[<span class="hljs-number">-1</span>]].sum()
</code></pre>
<p>And, sum of values in second last column of <code>confirmed_df</code>, <code>death_df</code> and <code>recovered_df</code> gives us the total number of respective cases for previous day.</p>
<pre><code class="lang-python">confirmed_df[confirmed_df.columns[<span class="hljs-number">-2</span>]].sum()
death_df[death_df.columns[<span class="hljs-number">-2</span>]].sum()
recovered_df[recovered_df.columns[<span class="hljs-number">-2</span>]].sum()
</code></pre>
<p>Subtracting these two values for respective cases yields us current day increase or decrease in respective cases.</p>
<pre><code class="lang-python">confirmed_today = int(confirmed_df[confirmed_df.columns[<span class="hljs-number">-1</span>]].sum() - confirmed_df[confirmed_df.columns[<span class="hljs-number">-2</span>]].sum())
death_today = int(death_df[death_df.columns[<span class="hljs-number">-1</span>]].sum() - death_df[death_df.columns[<span class="hljs-number">-2</span>]].sum())
recovered_today = int(recovered_df[recovered_df.columns[<span class="hljs-number">-1</span>]].sum() - recovered_df[recovered_df.columns[<span class="hljs-number">-2</span>]].sum())
</code></pre>
<h3 id="heading-displaying-a-table-of-20-countries-with-most-number-of-cases">Displaying a table of 20 Countries with Most Number of Cases</h3>
<p>We will display Country Name, Last Updated Time, Confirmed Cases, Death Cases and Required Cases in the table. The <code>country_df</code> has the required data that is to be displayed in the table. Let’s extract the required data from it.</p>
<pre><code class="lang-python">country_stats_df =
country_df[[‘country’, ‘last_update’,’confirmed’, ‘deaths’, ‘recovered’]].sort_values(<span class="hljs-string">'confirmed'</span>, ascending=<span class="hljs-literal">False</span>)
             .reset_index(drop=<span class="hljs-literal">True</span>)
             .head(<span class="hljs-number">20</span>)
</code></pre>
<p>This extracts the required columns from <code>country_df</code>, sorts the table in descending order of Confirmed Cases and returns top 20 rows into a new data frame called <code>country_stats_df</code></p>
<p>Now that we have the exact data we need to display in the table, we will add some styling to it to make it more readable and easier to interpret. We will change the font colour for Death Cases column to Red and Recovered Cases column to Green.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">highlight_col</span>(<span class="hljs-params">x</span>):</span>
  red = <span class="hljs-string">'color: #e73631'</span>
  black = <span class="hljs-string">'color: #000'</span>
  green = <span class="hljs-string">'color: #70a82c'</span>
  df1 = pd.DataFrame(<span class="hljs-string">''</span>, index=x.index, columns=x.columns)
  df1.iloc[:, <span class="hljs-number">2</span>] = black
  df1.iloc[:, <span class="hljs-number">3</span>] = red
  df1.iloc[:, <span class="hljs-number">4</span>] = green
  <span class="hljs-keyword">return</span> df1
</code></pre>
<p>We pass a data frame <code>x</code> to the function and copy it to <code>df1</code>. The three colours are defined in the function. <code>iloc</code> function is used to select rows and columns in the dataframe. The first argument is for selection of rows and second for that of column. Using <code>:</code> as an argument suggests that all the rows/columns are to be selected.</p>
<p>In Above function assigns respective colours to all rows of columns with index 2, 3 and 4.</p>
<p>Let’s apply this styling to our data frame and pass it to <code>st.table()</code> function of Streamlit library, to display the table.</p>
<pre><code class="lang-python">st.table(country_stats_df.style.apply(highlight_col, axis=<span class="hljs-literal">None</span>).set_properties(**{‘text-align’: ‘left’, ‘font-size’: ‘<span class="hljs-number">15</span>px’}))
</code></pre>
<h3 id="heading-creating-bar-chart-race-for-10-countries-with-most-number-of-cases">Creating Bar Chart Race for 10 Countries with Most Number of Cases</h3>
<p>An online tool called Flourish Studio makes it really easy to create an Bar Chart Race. All we need to need to do is load a <code>.csv</code> file into the tool and select which column is to be used as Labels on Y-axis and which columns are to be used for values on X-axis. The piece of code below can be used to export the data into <code>.csv</code> file called <code>latest_confirmed.csv</code> as required by Flourish Studio.</p>
<pre><code class="lang-python">latest_confirmed = confirmed_df.groupby([<span class="hljs-string">'Country/Region'</span>]).sum()
latest_confirmed.to_csv(<span class="hljs-string">'latest_confirmed.csv'</span>)
</code></pre>
<p><a target="_blank" href="https://app.flourish.studio/">Link to Flourish Studio</a></p>
<h2 id="heading-stats-for-a-specific-country">Stats for a Specific Country</h2>
<h3 id="heading-creating-a-dropdown-for-country-selection">Creating a dropdown for Country selection</h3>
<p><code>list_all_countries = list(confirmed_df[‘country’].unique())</code> creates a list of all the countries we have data for.</p>
<p><code>country_name = st.selectbox(‘’, list_all_countries, 71)</code> is used to create dropdown. Any value selected from the dropdown is assigned to <code>country_name</code>.</p>
<p><code>st.selectbox()</code> takes 3 arguments. A label for dropdown, list of values for dropdown and index of default value. I have passed 71 as default value index as it is index value for India.</p>
<h3 id="heading-calculating-total-confirmed-death-and-recovered-cases-for-selected-country">Calculating total Confirmed, Death and Recovered Cases for Selected Country</h3>
<p>First we create three new data frames from <code>confirmed_df</code>, <code>death_df</code> and <code>recovered_df</code> with only the data for specific country.</p>
<p>Then we calculate current day total, previous day total and their difference for current day change (exactly as done previously for World Data) for all three cases.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">show_country_stats</span>(<span class="hljs-params">country</span>):</span>
    country_confirmed_df = confirmed_df[confirmed_df[<span class="hljs-string">'country'</span>] == country]
    country_death_df = death_df[death_df[<span class="hljs-string">'country'</span>] == country]
    country_recovered_df = recovered_df[recovered_df[<span class="hljs-string">'country'</span>] == country]

    country_confirmed = country_confirmed_df[country_confirmed_df.columns[<span class="hljs-number">-1</span>]].sum()
    country_death = country_death_df[country_death_df.columns[<span class="hljs-number">-1</span>]].sum()
    country_recovered = country_recovered_df[country_recovered_df.columns[<span class="hljs-number">-1</span>]].sum()

    country_confirmed_today = int(country_confirmed_df[country_confirmed_df.columns[<span class="hljs-number">-1</span>]].sum()) - int(country_confirmed_df[country_confirmed_df.columns[<span class="hljs-number">-2</span>]].sum())
    country_death_today = int(country_death_df[country_death_df.columns[<span class="hljs-number">-1</span>]].sum()) - int(country_death_df[country_death_df.columns[<span class="hljs-number">-2</span>]].sum())
    country_recovered_today = int(country_recovered_df[country_recovered_df.columns[<span class="hljs-number">-1</span>]].sum()) - int(country_recovered_df[country_recovered_df.columns[<span class="hljs-number">-2</span>]].sum())
</code></pre>
<h3 id="heading-plotting-the-trend-for-confirmed-death-and-recovered-cases-for-selected-country">Plotting the trend for Confirmed, Death and Recovered Cases for selected Country</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">plot_cases_of_a_country</span>(<span class="hljs-params">country</span>):</span>
    labels = [<span class="hljs-string">'Confirmed'</span>, <span class="hljs-string">'Deaths'</span>, <span class="hljs-string">'Recovered'</span>]
    colors = [<span class="hljs-string">'black'</span>, <span class="hljs-string">'red'</span>, <span class="hljs-string">'green'</span>]
    mode_size = [<span class="hljs-number">8</span>, <span class="hljs-number">8</span>, <span class="hljs-number">8</span>]
    line_size = [<span class="hljs-number">5</span>, <span class="hljs-number">5</span>, <span class="hljs-number">5</span>]

    df_list = [confirmed_df, death_df, recovered_df]

    fig = go.Figure();

    <span class="hljs-keyword">for</span> i, df <span class="hljs-keyword">in</span> enumerate(df_list):
        x_data = np.array(list(df.iloc[:, <span class="hljs-number">4</span>:].columns))
        y_data = np.sum(np.asarray(df[df[<span class="hljs-string">'country'</span>] == country].iloc[:,<span class="hljs-number">4</span>:]),axis = <span class="hljs-number">0</span>)

        fig.add_trace(go.Scatter(x=x_data, y=y_data, mode=<span class="hljs-string">'lines+markers'</span>,
        name=labels[i],
        line=dict(color=colors[i], width=line_size[i]),
        connectgaps=<span class="hljs-literal">True</span>,
        text = <span class="hljs-string">"Total "</span> + str(labels[i]) +<span class="hljs-string">": "</span>+ str(y_data[<span class="hljs-number">-1</span>])
        ));

    fig.update_layout(
        title=<span class="hljs-string">"COVID 19 cases of "</span> + country,
        xaxis_title=<span class="hljs-string">'Date'</span>,
        yaxis_title=<span class="hljs-string">'No. of Confirmed Cases'</span>,
        margin=dict(l=<span class="hljs-number">20</span>, r=<span class="hljs-number">20</span>, t=<span class="hljs-number">40</span>, b=<span class="hljs-number">20</span>),
        paper_bgcolor=<span class="hljs-string">'#f5f5f5'</span>,
        plot_bgcolor=<span class="hljs-string">'rgba(0,0,0,0)'</span>
    );

    fig.update_yaxes(type=<span class="hljs-string">"linear"</span>)
    <span class="hljs-keyword">return</span> fig
</code></pre>
<p>We pass selected country as parameter in the function. Labels, colours, marker size and line size are defined for each case.</p>
<p>Labels for X-axis are Dates i.e the columns starting from index=4 and values for plotting on Y-axis are the sum of values in these columns for selected country.</p>
<p>As we have 3 data frames in <code>df_list</code>, the for loop runs for all 3 data frames, plotting graphs for respective case at the end of each iteration.</p>
<h3 id="heading-plotting-daily-increase-in-number-of-confirmed-cases-for-selected-country">Plotting Daily Increase in number of Confirmed Cases for selected Country</h3>
<p>We will use <code>delta_df</code> to plot the daily increase in number of Confirmed Cases.</p>
<p>We first extract the required columns from <code>delta_df</code>:</p>
<pre><code class="lang-python">delta_df = delta_df[[<span class="hljs-string">'Country_Region'</span>, <span class="hljs-string">'Delta_Confirmed'</span>, <span class="hljs-string">'Last_Update'</span>]]
</code></pre>
<p>The current structure of <code>delta_df</code> is as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601065797586/k9JhCnmBA.png" alt="dataframe2.png" /></p>
<p>This structure is not at all useful to create any plot. We either need Date as columns and Date as index or vice versa. So, we will pivot the table as per our need. We will set Date as index and Country Names as columns.</p>
<pre><code class="lang-python">delta_pivoted_df = delta_df.pivot_table(index=<span class="hljs-string">'date'</span>, columns=<span class="hljs-string">'country_name'</span>, values=<span class="hljs-string">'delta_confirmed'</span>, aggfunc=np.sum)
delta_pivoted_df.reset_index(level=<span class="hljs-number">0</span>, inplace=<span class="hljs-literal">True</span>)
</code></pre>
<p>After this restructuring of <code>delta_df</code>, it is changed as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1601065810283/DCSo5SmDP.png" alt="dataframe3.png" /></p>
<p>We add a new column named ‘World’ which contains the sum of number of confirmed cases of all countries.</p>
<pre><code class="lang-python">delta_world_df[<span class="hljs-string">'World'</span>] = delta_pivoted_df[delta_pivoted_df.columns].sum(axis=<span class="hljs-number">1</span>)
</code></pre>
<p>Now we can use this data frame to plot a bar graph where the values in date column form X-axis and those in column of selected country form Y-axis.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">plot_new_cases_of_country</span>(<span class="hljs-params">country</span>):</span>
    <span class="hljs-keyword">if</span>(country == <span class="hljs-string">'World'</span> <span class="hljs-keyword">or</span> country == <span class="hljs-string">'world'</span>):
        y_data = np.array(list(delta_world_df[country]))
    <span class="hljs-keyword">elif</span>(country == <span class="hljs-string">'US'</span>):
        y_list = list(delta_pivoted_df[country])
        y_list = [x / <span class="hljs-number">2</span> <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> y_list]
        y_data = np.array(y_list)
    <span class="hljs-keyword">else</span>:
        y_data = np.array(list(delta_pivoted_df[country]))
    x_data = np.array(list(delta_df[<span class="hljs-string">'date'</span>]))
    fig = go.Figure()
    fig.add_trace(go.Bar(
        x=x_data,
        y=y_data,
        name=<span class="hljs-string">'Daily Increase'</span>,
        marker_color=<span class="hljs-string">'crimson'</span>,
        hovertemplate=<span class="hljs-string">'Date: %{x}; \n  New Cases: %{y}'</span>,
    ))
    fig.update_layout(
            title=<span class="hljs-string">"Daily increase in cases of "</span> + country,
            xaxis_title=<span class="hljs-string">'Date'</span>,
            yaxis_title=<span class="hljs-string">'No. of New Cases'</span>,
            margin=dict(l=<span class="hljs-number">20</span>, r=<span class="hljs-number">20</span>, t=<span class="hljs-number">40</span>, b=<span class="hljs-number">20</span>),
            paper_bgcolor=<span class="hljs-string">'#F6F6F7'</span>,
            plot_bgcolor=<span class="hljs-string">'rgba(0,0,0,0)'</span>,
    );
    fig.update_yaxes(type=<span class="hljs-string">"linear"</span>)
    <span class="hljs-keyword">return</span> fig
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>To keep it simple and easy to understand, I have kept my focus on Data Science aspect of the project. The designing part which uses HTML and CSS (Bootstrap) is not discussed in this blog. You can checkout the source code, <a target="_blank" href="https://github.com/desaihetav/Streamlit-COVID-19-Dashboard/blob/master/app.py">here</a>.</p>
<p>Thank you very much for reading this article and if you found it useful, please do share it with your friends or anyone who may benefit from this.</p>
<p>If you have any questions or want to discuss ideas, please feel free to reach out to me through your preferred medium of communication.</p>
<p>Get in touch with me on <a target="_blank" href="https://www.twitter.com/desaihetav">Twitter</a>, <a target="_blank" href="https://www.linkedin.com/in/desaihetav/">LinkedIn</a> or <a target="_blank" href="https://www.instagram.com/desaihetav/">Instagram</a>.</p>
]]></content:encoded></item></channel></rss>