<?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>Forem: Vimalraj Selvam</title>
    <description>The latest articles on Forem by Vimalraj Selvam (@email2vimalraj).</description>
    <link>https://forem.com/email2vimalraj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38540%2Ff3441304-f002-4e85-9f2d-0ebfef492f5a.jpeg</url>
      <title>Forem: Vimalraj Selvam</title>
      <link>https://forem.com/email2vimalraj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/email2vimalraj"/>
    <language>en</language>
    <item>
      <title>Collect Failed Task Details in Ansible</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Mon, 05 Jul 2021 15:08:12 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/collect-failed-task-details-in-ansible-4hcf</link>
      <guid>https://forem.com/email2vimalraj/collect-failed-task-details-in-ansible-4hcf</guid>
      <description>&lt;p&gt;Recently, I've started working on Ansible to help our organization to roll out &lt;a href="https://github.com/prometheus/node_exporter"&gt;Node Exporter&lt;/a&gt; in a wide scale. I've had few struggles during this journey and I believe each struggles teaches something. Hence I'll be starting few series about my struggles and what I learnt from that.&lt;/p&gt;

&lt;p&gt;I know, first of all a big apologies to all of you, my dear readers. It's been quite a while I didn't blog. Lately, I've got busy with my day-to-day work and seriously didn't get much time (reason below). I'll try to blog as much as possible. Hope you all doing well during this pandemic. Let's jump on to the topic&lt;/p&gt;

&lt;p&gt;Today, I would like to share a very useful tip which I struggled a lot to find it online. This is about collecting some useful information about failures in ansible, so that it will help you to perform some post validation after the execution across many servers.&lt;/p&gt;

&lt;p&gt;For an example, in my case, we had to roll out &lt;a href="https://github.com/prometheus/node_exporter"&gt;Node Exporter&lt;/a&gt; across 60k+ linux servers. And it was a nightmare if something failes and try to perform validation on why the failure was. Hence, we need some kind of reporting which can tell us some details about the server and the task which was failed with failure reason. I'm glad we nailed this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Intentionally failing here&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Node Exporter&lt;/span&gt;
        &lt;span class="na"&gt;fail&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Failed intentionally&lt;/span&gt;
    &lt;span class="na"&gt;rescue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Record failure&lt;/span&gt;
        &lt;span class="na"&gt;lineinfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp/execution-failures.csv&lt;/span&gt;
          &lt;span class="na"&gt;line&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;"{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;inventory_hostname&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}","{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tower_job_id&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}","{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ansible_failed_task['&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name'&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}","{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ansible_failed_result['&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;module_stderr'&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}","{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ansible_failed_result['&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;stdout'&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"'&lt;/span&gt;
          &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
        &lt;span class="na"&gt;delegate_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;centralized.host.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trick here is &lt;code&gt;block...rescue&lt;/code&gt; and in &lt;code&gt;rescue&lt;/code&gt; capture some required key details for the validation. Here I'm capturing the following details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;inventory_hostname&lt;/code&gt;: The destination host where the playbook is executed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tower_job_id&lt;/code&gt;: The ansible tower job id. Recording this in case if any ansible issues found, we'll report to ansible team with this detail for them to debug and help.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ansible_failed_task['name']&lt;/code&gt;: Name of the failed task.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ansible_failed_result['module_stderr']&lt;/code&gt;: Captures the stderr of the failed task. This is more important for us because this gives us details about the failure reason.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ansible_failed_result['stdout']&lt;/code&gt;: This will be empty in most of the cases as the failed task will contain only &lt;code&gt;stderr&lt;/code&gt;, not &lt;code&gt;stdout&lt;/code&gt;. Keeping this for any unexpected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope this helps. Shoot me with your questions here: &lt;a href="https://github.com/email2vimalraj/site/issues/new"&gt;https://github.com/email2vimalraj/site/issues/new&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published here: &lt;a href="https://vimalselvam.com/post/ansible-collect-failed-tasks/"&gt;https://vimalselvam.com/post/ansible-collect-failed-tasks/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>prometheus</category>
      <category>nodeexporter</category>
    </item>
    <item>
      <title>Capturing Username in Process Exporter with Prometheus</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Sun, 06 Dec 2020 22:31:19 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/capturing-username-in-process-exporter-with-prometheus-je2</link>
      <guid>https://forem.com/email2vimalraj/capturing-username-in-process-exporter-with-prometheus-je2</guid>
      <description>&lt;p&gt;Originally posted in: &lt;a href="https://vimalselvam.com/post/prometheus-capturing-username-in-process-exporter/"&gt;https://vimalselvam.com/post/prometheus-capturing-username-in-process-exporter/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, stumbled upon a task where we wanted to capture the username of the process with the &lt;a href="https://github.com/ncabatoff/process-exporter"&gt;process exporter&lt;/a&gt; and store as a label in prometheus. There is no clear documentation around this on how to accomplish. So I thought let's share what I've learnt which I believe might be useful for someone.&lt;/p&gt;

&lt;p&gt;Let's see how to capture the username in the &lt;a href="https://github.com/ncabatoff/process-exporter"&gt;process exporter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You should be having prometheus running. In case you want to know how to setup, head &lt;a href="https://prometheus.io/docs/prometheus/latest/getting_started/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;To setup the process exporter, refer &lt;a href="https://github.com/ncabatoff/process-exporter"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Process Exporter Config
&lt;/h2&gt;

&lt;p&gt;To make process exporter mine a required process, I've the following sample config &lt;code&gt;yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;process_names&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{.ExeBase}}"&lt;/span&gt;
    &lt;span class="na"&gt;cmdline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;crond'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ExeBase&lt;/code&gt; is the basename of the executable which I wanted to capture. Now I would like to know the user who is executing the &lt;code&gt;crond&lt;/code&gt; process. So I'll change the &lt;code&gt;yaml&lt;/code&gt; to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;process_names&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{.ExeBase}};{{.Username}}"&lt;/span&gt;
    &lt;span class="na"&gt;cmdline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;crond'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I've added &lt;code&gt;;{{.Username}}&lt;/code&gt;, the &lt;code&gt;Username&lt;/code&gt; captures the user of the given process, here it is &lt;code&gt;crond&lt;/code&gt;. The reason that I've added semicolon(&lt;code&gt;;&lt;/code&gt;) is because I'll use the &lt;a href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs"&gt;metric_relabel_configs&lt;/a&gt; in prometheus scrape config to split and store username as a separate label.&lt;/p&gt;

&lt;p&gt;I've stored the file as &lt;code&gt;proc-config.yaml&lt;/code&gt; and will start the process exporter as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; process-exporter &lt;span class="nt"&gt;-config&lt;/span&gt;.path proc-config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, if you scrape the process exporter (&lt;a href="http://localhost:9256/metrics"&gt;http://localhost:9256/metrics&lt;/a&gt;), you will get the metrics in the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namedprocess_namegroup_num_procs{groupname='crond;vimalraj'} 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;groupname&lt;/code&gt; says the &lt;code&gt;crond&lt;/code&gt; process and triggered by user &lt;code&gt;vimalraj&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's look at how we configure prometheus to store the user as a separate label.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prometheus Config
&lt;/h2&gt;

&lt;p&gt;Open up the &lt;code&gt;prometheus.yml&lt;/code&gt; file and add the new scrape target as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;process_exporter'&lt;/span&gt;
    &lt;span class="na"&gt;scrape_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15s&lt;/span&gt;
    &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localhost:9256&lt;/span&gt;
    &lt;span class="na"&gt;metric_relabel_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;groupname"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# the label which needs to be filtered&lt;/span&gt;
        &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(.*);(.*)"&lt;/span&gt;            &lt;span class="c1"&gt;# the regex to find the expected match&lt;/span&gt;
        &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;processname"&lt;/span&gt;   &lt;span class="c1"&gt;# add a new label&lt;/span&gt;
        &lt;span class="na"&gt;replacement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$1"&lt;/span&gt;             &lt;span class="c1"&gt;# substitute with the 1st match&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source_labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;groupname"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# the label which needs to be filtered&lt;/span&gt;
        &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(.*);(.*)"&lt;/span&gt;            &lt;span class="c1"&gt;# the regex to find the expected match&lt;/span&gt;
        &lt;span class="na"&gt;target_label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username"&lt;/span&gt;      &lt;span class="c1"&gt;# add a new label&lt;/span&gt;
        &lt;span class="na"&gt;replacement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$2"&lt;/span&gt;             &lt;span class="c1"&gt;# substitute with the 2nd match&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To know more about the &lt;code&gt;metric_relabel_configs&lt;/code&gt;, refer prometheus documentation &lt;a href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now reload the config and query for &lt;code&gt;namedprocess_namegroup_num_procs&lt;/code&gt;. You should be seeing the following result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namedprocess_namegroup_num_procs{groupname='crond;vimalraj', processname='crond', username='vimalraj'} 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that I kept &lt;code&gt;groupname&lt;/code&gt; as it is, in case you want to remove, you can use &lt;code&gt;action&lt;/code&gt; to drop that label.&lt;/p&gt;

&lt;p&gt;In case you found this post useful, please do share it. For any questions, feel free to open an &lt;code&gt;issue&lt;/code&gt; &lt;a href="https://github.com/email2vimalraj/site/issues"&gt;here&lt;/a&gt; to discuss further.&lt;/p&gt;

</description>
      <category>prometheus</category>
      <category>monitoring</category>
      <category>processexporter</category>
    </item>
    <item>
      <title>Cancel / Unsubscribe GraphQL Subscription</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Fri, 24 Jul 2020 07:00:50 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/cancel-unsubscribe-graphql-subscription-55oe</link>
      <guid>https://forem.com/email2vimalraj/cancel-unsubscribe-graphql-subscription-55oe</guid>
      <description>&lt;p&gt;&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is one of my favourite topic to work with. At my &lt;a href="https://www.linkedin.com/in/vimalraj-selvam/" rel="noopener noreferrer"&gt;work&lt;/a&gt;, as a Site Reliability Engineer, I often work on Visualisation products and the backend is powered with GraphQL. When it comes to Visualisation, the real-time data is the user need and the GraphQL has something called &lt;strong&gt;Subscription&lt;/strong&gt; which works on top of Web Sockets protocol.&lt;/p&gt;

&lt;p&gt;A subscription is needed when you wanted to publish the data set to all the clients who subscribed / expressed their wish to receive updates. Here the client won't be polling for the data, rather server will be sending the data to all the subscribed clients whenever new data available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;We use GraphQL subscriptions for the real-time metrics data and show some graphs. When a user clicks on any graph panel, the modal will open up to perform slices and dices on the data. So the requirement is to cancel the subscription (aka. unsubscribe) when a user opens the modal. And re-subscribe when user closes the modal. Interesting, isn't it? Let's see how we can do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a GraphQL Subscription server
&lt;/h2&gt;

&lt;p&gt;To demonstrate, I'm going to create a simple GraphQL Subscription server.&lt;/p&gt;

&lt;p&gt;Currently I'm on a directory called, &lt;strong&gt;graphql-subscription-demo&lt;/strong&gt;, and I'm going to create a new directory here and setup the required npm packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;server
&lt;span class="nb"&gt;cd &lt;/span&gt;server
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm i &lt;span class="nt"&gt;-S&lt;/span&gt; graphql express apollo-server apollo-server-express
&lt;span class="nb"&gt;touch &lt;/span&gt;index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in &lt;code&gt;index.js&lt;/code&gt; I'm going to create the following code snippet.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PubSub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo-server-express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Required constants&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COUNT_INCREMENTED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COUNT_INCREMENTED&lt;/span&gt;&lt;span class="dl"&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;4000&lt;/span&gt;

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

&lt;span class="c1"&gt;// Create pubsub instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pubsub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PubSub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// initiate counter&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;// Keep incrementing the counter for every 3 seconds&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&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;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="c1"&gt;// Publish the incremented counter value&lt;/span&gt;
  &lt;span class="nx"&gt;pubsub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COUNT_INCREMENTED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;3000&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;typeDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  type Query {
    """
    Get the current counter value
    """
    count: Int
  }

  type Subscription {
    """
    Publish the count value whenever it increments
    """
    count: Int
  }
`&lt;/span&gt;

&lt;span class="c1"&gt;// GraphQL Resolver&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&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;count&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;Subscription&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// This is where we listen to an event called COUNT_INCREMENTED and publish when an event triggered&lt;/span&gt;
      &lt;span class="na"&gt;subscribe&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;pubsub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asyncIterator&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;COUNT_INCREMENTED&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="c1"&gt;// Create apollo server&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;applyMiddleware&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;const&lt;/span&gt; &lt;span class="nx"&gt;httpServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&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;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;installSubscriptionHandlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;httpServer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Start the http and websocket server on our port&lt;/span&gt;
&lt;span class="nx"&gt;httpServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server on http://localhost:&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;graphqlPath&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`Subscriptions on ws://localhost:&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptionsPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this snippet, I do the following things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Importing the required packages&lt;/li&gt;
&lt;li&gt;Defining constants:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;COUNT_INCREMENTED&lt;/strong&gt; - A string constant to use it as a identifier for our event&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PORT&lt;/strong&gt; - A port number where our server will run&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Creating an instance for the &lt;strong&gt;express&lt;/strong&gt; app and the &lt;strong&gt;PubSub&lt;/strong&gt; to manage our GraphQL subscriptions&lt;/li&gt;

&lt;li&gt;Initialising a counter variable with value as 1&lt;/li&gt;

&lt;li&gt;Incrementing the counter by 1 for every 3 seconds and also publishing the incremented value using our constant identifier&lt;/li&gt;

&lt;li&gt;Defined a GraphQL document with &lt;code&gt;Query&lt;/code&gt; to get the current count value and &lt;code&gt;Subscription&lt;/code&gt; to publish the count value whenever it is incremented&lt;/li&gt;

&lt;li&gt;Defined a GraphQL resolver

&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;subscribe&lt;/code&gt;, we listen to a variable called &lt;code&gt;COUNT_INCREMENTED&lt;/code&gt; ****and publishes to subscribed clients if the payload changes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Creating a Apollo server and HTTP server with required subscription handlers&lt;/li&gt;

&lt;li&gt;Starting the HTTP and Websocket server on the defined port&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Once you have the above code in place, just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the server and you can access the GraphQL playground from: &lt;a href="http://localhost:4000/graphql" rel="noopener noreferrer"&gt;http://localhost:4000/graphql&lt;/a&gt;. You can play around with the query and subscription here before starting our real client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a GraphQL Client application
&lt;/h2&gt;

&lt;p&gt;I'm going to use React to create a GraphQL client application. To create a react app and install required packages (remember I was inside &lt;strong&gt;server&lt;/strong&gt; directory),&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
npx create-react-app client &lt;span class="nt"&gt;--use-npm&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;client
npm i &lt;span class="nt"&gt;-S&lt;/span&gt; graphql @apollo/client subscriptions-transport-ws
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;P.S: I'm using the recently announced Apollo Client @ 3.x version. Apart from the package name, the implementation holds same even for Apollo Client @ 2.x version.&lt;/p&gt;

&lt;p&gt;Now straightaway go to &lt;code&gt;App.js&lt;/code&gt; and remove everything. You follow me from this onwards:&lt;/p&gt;

&lt;p&gt;First import the required packages:&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="c1"&gt;// I'm a big fan of Ant Design, but you can use any design system&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;Layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Modal&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;antd&lt;/span&gt;&lt;span class="dl"&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;ApolloClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;InMemoryCache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ApolloProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;HttpLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;split&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;@apollo/client&lt;/span&gt;&lt;span class="dl"&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;WebSocketLink&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;@apollo/client/link/ws&lt;/span&gt;&lt;span class="dl"&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;getMainDefinition&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;@apollo/client/utilities&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a http link to  send our Query / Mutation using the HTTP Protocol:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;httpLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpLink&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Server GraphQL endpoint&lt;/span&gt;
  &lt;span class="na"&gt;uri&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://localhost:4000/graphql&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;Next, create a Websocket link for our subscription handler:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subscriptionLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocketLink&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Server GraphQL Subscription endpoint&lt;/span&gt;
  &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ws://localhost:4000/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Reconnect in case client disconnects and connects again&lt;/span&gt;
    &lt;span class="na"&gt;reconnect&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now merge both the links and create a Apollo client out of the merged link:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;splitLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;definition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMainDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OperationDefinition&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;subscriptionLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;httpLink&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApolloClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;splitLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InMemoryCache&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// In memory cache&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 define our &lt;code&gt;Query&lt;/code&gt; and &lt;code&gt;Subscription&lt;/code&gt;:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COUNT_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query CountQuery {
    count
  }
`&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COUNT_SUBSCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  subscription CountSubscription {
    count
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's define our &lt;code&gt;App&lt;/code&gt; functional component:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ApolloProvider&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100vh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&lt;/span&gt;
          &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Row&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;Col&lt;/span&gt; &lt;span class="na"&gt;span&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;16px 0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&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;Col&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;Row&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;Layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Layout&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;ApolloProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we're wrapping everything with &lt;code&gt;ApolloProvider&lt;/code&gt; and initiating with the &lt;code&gt;client&lt;/code&gt;. It is the React's context where any changes to the &lt;code&gt;client&lt;/code&gt; object will re-render the child components. And also this is very much required, because we will be using the Apollo Client's hooks in the child components.&lt;/p&gt;

&lt;p&gt;If you notice, we have a missing component &lt;code&gt;&amp;lt;Counter /&amp;gt;&lt;/code&gt;, let's define that. Create a function called &lt;code&gt;Counter&lt;/code&gt; and put the following code:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COUNT_QUERY&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;modalVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setModalVisible&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&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;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pointer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setModalVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;modalVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error :(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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;Modal&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Drill down"&lt;/span&gt;
        &lt;span class="na"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;modalVisible&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onOk&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setModalVisible&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="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onCancel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setModalVisible&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="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Drill down here&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&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;Modal&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&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;In this component, we trigger a GraphQL query &lt;code&gt;COUNT_QUERY&lt;/code&gt; at the time of rendering this component and show the current count value using &lt;code&gt;data.count&lt;/code&gt;. If user clicks on the count, it will open up the modal and show some dummy content.&lt;/p&gt;

&lt;p&gt;Now head to your browser and see &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;. If you notice, even though the count is incremented at the server side, the client is not updating. Reason is we haven't hooked up the subscription part yet. Let's do that now!&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;subscribeToMore&lt;/code&gt; field in the &lt;code&gt;useQuery&lt;/code&gt; hook as follows. The reason I'm using &lt;code&gt;subscribeToMore&lt;/code&gt; rather than &lt;code&gt;useSubscription&lt;/code&gt; hook is because I want to show the current value once the user loads the page and doesn't really want to show the loading indicator for the 3 seconds when the subscription has not published the new value yet.&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subscribeToMore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COUNT_QUERY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then define the &lt;code&gt;useEffect&lt;/code&gt; to initiate the subscription during the component rendering. To know more about &lt;code&gt;useEffect&lt;/code&gt;, read &lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/" rel="noopener noreferrer"&gt;this&lt;/a&gt;.&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="nx"&gt;React&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="nf"&gt;subscribeToMore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;COUNT_SUBSCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;updateQuery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;subscriptionData&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;subscriptionData&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;prev&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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;subscriptionData&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;count&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;span class="nx"&gt;subscribeToMore&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I'm calling a &lt;code&gt;subscribeToMore&lt;/code&gt; method with the &lt;code&gt;COUNT_SUBSCRIPTION&lt;/code&gt; graphQL document and client gets subscribed to the stream. Please note that I've added a &lt;code&gt;useEffect&lt;/code&gt; dependence for &lt;code&gt;subscribeToMore&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Now look in your browser and you can see the count gets updated every 3 seconds whenever server increments. Voila! Our subscription works.&lt;/p&gt;

&lt;p&gt;Small tip: Open Developer console, and head on to Network tab, select &lt;code&gt;WS&lt;/code&gt; to see the websocket messages, you should see something 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%2Fi%2F5lm9c103f2i07yfq2l86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5lm9c103f2i07yfq2l86.png" alt="Subscription dev tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you can see that the payload is continuously sent to client by the server. Now we're going to see the real problem. Just click on the counter, and you see the modal and the subscription still receiving data. This is where we have to unsubscribe.&lt;/p&gt;

&lt;p&gt;Let's modify our &lt;code&gt;useEffect&lt;/code&gt; method little bit as follows:&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="nx"&gt;React&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;let&lt;/span&gt; &lt;span class="nx"&gt;unsubscribe&lt;/span&gt;

    &lt;span class="c1"&gt;// If modal is not visible, run the subscription and store the identifier in the `unsubscribe` variable&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;modalVisible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;unsubscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;subscribeToMore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;COUNT_SUBSCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;updateQuery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;subscriptionData&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;subscriptionData&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;prev&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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;subscriptionData&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;count&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="c1"&gt;// Unsubscribe here&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;unsubscribe&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;gt;&lt;/span&gt; &lt;span class="nf"&gt;unsubscribe&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;modalVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subscribeToMore&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you look at this we're subscribing to event when the modal is not visible and store that in a variable called &lt;code&gt;unsubscribe&lt;/code&gt;. In the clean up method of &lt;code&gt;useEffect&lt;/code&gt;, we just call the &lt;code&gt;unsubscribe&lt;/code&gt; to cancel our graphql subscription. Also, remember to add &lt;code&gt;modalVisible&lt;/code&gt; as another dependency to our hook. This does the magic. Let's head on to our browser to validate 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%2Fi%2F1abkdgvsi2nbknykd7wm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1abkdgvsi2nbknykd7wm.png" alt="Cancel Subscription - Devtool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the browser, when the real time update is happening and your Developer console is opened, just click on the count value and let the modal open. And notice the messages and you see a &lt;code&gt;stop&lt;/code&gt; type which means cancel the GraphQL subscription, the client won't be receiving any updates from the server until we close the modal.&lt;/p&gt;

&lt;p&gt;The entire running code is available in Github:  &lt;a href="https://github.com/email2vimalraj/graphql-subscription-demo" rel="noopener noreferrer"&gt;https://github.com/email2vimalraj/graphql-subscription-demo&lt;/a&gt; (If you have any questions, open up an issue here and also make sure you &lt;strong&gt;star&lt;/strong&gt; the repo if you liked this article).&lt;/p&gt;

&lt;p&gt;Last year I talked about Scaling GraphQL Subscriptions @ GraphQL Conf happened in Berlin (in case you're interested to watch): &lt;a href="https://youtu.be/k4rX8wUYjmU" rel="noopener noreferrer"&gt;https://youtu.be/k4rX8wUYjmU&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;https://graphql.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.apollographql.com/docs/" rel="noopener noreferrer"&gt;https://www.apollographql.com/docs/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ant.design/docs/react/introduce" rel="noopener noreferrer"&gt;https://ant.design/docs/react/introduce&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published in my &lt;a href="https://vimalselvam.com/post/unsubscribe-graphql-subscription/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Asynchronous processing of data in Expressjs</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Thu, 23 Apr 2020 06:57:39 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/asynchronous-processing-of-data-in-expressjs-3a70</link>
      <guid>https://forem.com/email2vimalraj/asynchronous-processing-of-data-in-expressjs-3a70</guid>
      <description>&lt;p&gt;I've an Express route which receives some data and process it, then insert into mongo (using mongoose).&lt;/p&gt;

&lt;p&gt;This is working well if I return a response after the following steps are done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receive request&lt;/li&gt;
&lt;li&gt;Process the request data&lt;/li&gt;
&lt;li&gt;Insert the processed data into Mongo&lt;/li&gt;
&lt;li&gt;Return 204 response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But client will be calling this API concurrently for millions of records. Hence the requirement is not to block the client for processing the data. Hence I made a small change in the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receive request&lt;/li&gt;
&lt;li&gt;Return response immediately with 204&lt;/li&gt;
&lt;li&gt;Process the requested data&lt;/li&gt;
&lt;li&gt;Insert the processed data into Mongo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above is working fine for the first few requests (say 1000s), after that client is getting &lt;code&gt;socket exception: connection reset peer&lt;/code&gt; error. I guess it is because server is blocking the connection as the port is not free and at some point of time, I notice my nodejs process is throwing out &lt;code&gt;Out of memory&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;Sample code is as follows:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Process the data&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Insert the data in mongo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;expressController&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;received request&lt;/span&gt;&lt;span class="dl"&gt;'&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;204&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;enqueue&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;body&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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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;Am I doing something wrong here?&lt;/p&gt;

</description>
      <category>help</category>
      <category>node</category>
      <category>express</category>
    </item>
    <item>
      <title>Codemod with jscodeshift help needed</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Mon, 02 Sep 2019 15:38:21 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/codemod-with-jscodeshift-help-needed-629</link>
      <guid>https://forem.com/email2vimalraj/codemod-with-jscodeshift-help-needed-629</guid>
      <description>&lt;p&gt;I'm trying to write a small codemod to refactor some of the code. Consider I've somethihng 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mod1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mod2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mod3&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;package1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;localMod&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;package2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and I wanted to change this to:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mod1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mod3&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;package1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;mod2&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;new-package&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;localMod&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;package2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As a first step, I'm trying to remove &lt;code&gt;mod2&lt;/code&gt; from the 1st line of import which I did successfully, but I'm not able to remove the comma after &lt;code&gt;mod1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;My code snippet so far look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Please help.&lt;/p&gt;

</description>
      <category>help</category>
      <category>jscodeshift</category>
      <category>codemod</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introducing Test GraphQL Java</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Sat, 01 Jun 2019 23:21:04 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/introducing-test-graphql-java-4i7h</link>
      <guid>https://forem.com/email2vimalraj/introducing-test-graphql-java-4i7h</guid>
      <description>&lt;p&gt;I was recently asked by one of my friend how can we test the GraphQL APIs in Java. He is currently exploring &lt;code&gt;Karate's&lt;/code&gt; capability, however, he doesn’t want to use &lt;code&gt;Karate&lt;/code&gt; just for this as they’re already using &lt;code&gt;TestNG&lt;/code&gt; based framework. And there is a &lt;a href="https://github.com/graphql-java/graphql-java"&gt;graphql-java&lt;/a&gt; library which let’s you to implement &lt;code&gt;GraphQL&lt;/code&gt; in Java and test, but using Spring Boot. My main goal is not to introduce Spring Boot just for the sake of testing the &lt;code&gt;GraphQL&lt;/code&gt; API. I wanted to keep it simple!&lt;/p&gt;

&lt;p&gt;Goals were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should not bring various dependencies (this library currently depends only on &lt;code&gt;jackson&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Should just turn the graphql file into request payload string.&lt;/li&gt;
&lt;li&gt;Should be able to use any HTTP client library.&lt;/li&gt;
&lt;li&gt;Should be able to use any Java testing framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is how this library born. Let’s directly jump in how can we use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Adding maven dependency:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.vimalselvam&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;test-graphql-java&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I don’t use &lt;code&gt;Gradle&lt;/code&gt;, but it should be straight forward to add this library as a &lt;code&gt;Gradle&lt;/code&gt; dependency.&lt;/p&gt;

&lt;p&gt;Let’s test the &lt;a href="https://graphql-pokemon.now.sh/"&gt;Pokemon GraphQL API&lt;/a&gt;. We’re going to test the following query:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query pokemon {
  pokemon(name: "Pikachu") {
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We’ll trigger this query and assert the successful response code and the response body where the &lt;code&gt;name&lt;/code&gt; key contains &lt;code&gt;Pikachu&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take the above query and put it into a &lt;code&gt;pokemon.graphql&lt;/code&gt; under &lt;code&gt;src/test/resources/graphql/&lt;/code&gt; in your maven project directory.&lt;/p&gt;

&lt;p&gt;We can load this file in our test using either of the following two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using &lt;code&gt;InputStream&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InputStream iStream = getClass().getResourceAsStream("/graphql/pokemon.graphql");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;using &lt;code&gt;File&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;File file = new File("src/test/resources/graphql/pokemon.graphql");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For this example, I’m using the 2nd approach, &lt;code&gt;File&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you read the file, just pass it to &lt;code&gt;GraphqlTemplate&lt;/code&gt; class to parse as follows:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String graphqlPayload = GraphqlTemplate.parseGraphql(file, null);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The 2nd argument is &lt;code&gt;variables&lt;/code&gt; which is used to parameterize your GraphQL query. I’ll show you how to use that in a short while, till that let’s keep it &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That’s it! You now have the graphql query string which you can directly pass as a request payload on your preferred HTTP client library.&lt;/p&gt;

&lt;p&gt;Let’s talk about &lt;code&gt;variables&lt;/code&gt;. The &lt;code&gt;GraphQL&lt;/code&gt; has a feature to set some &lt;code&gt;variables&lt;/code&gt; and pass those variables at run time during execution of query. For that, we’ll modify our &lt;code&gt;Pokemon&lt;/code&gt; query.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;pokemon.graphql&lt;/code&gt; file and change it as:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query pokemon($name:String!) {
  pokemon(name: $name) {
    name
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;$name&lt;/code&gt; is the variable and it accepts only &lt;code&gt;String&lt;/code&gt;. The &lt;code&gt;!&lt;/code&gt; operator denotes that this is mandatory variable. Let’s see how we can handle this &lt;code&gt;variables&lt;/code&gt; scenario in our code.&lt;/p&gt;

&lt;p&gt;Before converting the GraphQL query to the plain string, let’s create the variables:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ObjectNode variables = new ObjectMapper().createObjectNode();
variables.put("name", "Pikachu");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we’re using &lt;code&gt;com.fasterxml.jackson.databind.node.ObjectNode&lt;/code&gt; to create variables. This &lt;code&gt;ObjectNode&lt;/code&gt; can be passed as 2nd parameter in our &lt;code&gt;GraphqlTemplate&lt;/code&gt; class.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String graphqlPayload = GraphqlTemplate.parseGraphql(file, variables);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That simple it is!&lt;/p&gt;

&lt;p&gt;I’ve open sourced this library and can be found here: &lt;a href="https://github.com/vimalrajselvam/test-graphql-java"&gt;https://github.com/vimalrajselvam/test-graphql-java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Contributions are welcome. If you have any thoughts or issues, kindly open an issue in the above github link.&lt;/p&gt;

&lt;p&gt;Let’s see the full example code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight mosel"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vimalselvam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.*;&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fasterxml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jackson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;databind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JsonNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fasterxml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jackson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;databind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fasterxml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jackson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;databind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ObjectNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;testng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;testng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;okhttp3&lt;/span&gt;&lt;span class="p"&gt;.*;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="n"&gt;TestClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;private&lt;/span&gt; &lt;span class="n"&gt;static&lt;/span&gt; &lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="n"&gt;OkHttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OkHttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;private&lt;/span&gt; &lt;span class="n"&gt;final&lt;/span&gt; &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;graphqlUri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://graphql-pokemon.now.sh/graphql"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;prepareResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;graphqlPayload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;RequestBody&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RequestBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"application/json; charset=utf-8"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;graphqlPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphqlUri&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;newCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;execute&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="n"&gt;Test&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;testGraphqlWithInputStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;
        &lt;span class="n"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;iStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TestClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getResourceAsStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/graphql/pokemon.graphql"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
        &lt;span class="n"&gt;ObjectNode&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;createObjectNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Pikachu"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Now&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;string&lt;/span&gt;
        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;graphqlPayload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GraphqlTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parseGraphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Build&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;trigger&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
        &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prepareResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphqlPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Response Code Assertion"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;JsonNode&lt;/span&gt; &lt;span class="n"&gt;jsonNode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;readTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pokemon"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;asText&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s2"&gt;"Pikachu"&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="n"&gt;Test&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;testGraphqlWithFile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"src/test/resources/graphql/pokemon.graphql"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;
        &lt;span class="n"&gt;ObjectNode&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;createObjectNode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Pikachu"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Now&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;string&lt;/span&gt;
        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;graphqlPayload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GraphqlTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parseGraphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Build&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;trigger&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
        &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prepareResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphqlPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Response Code Assertion"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;JsonNode&lt;/span&gt; &lt;span class="n"&gt;jsonNode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;readTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pokemon"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;asText&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s2"&gt;"Pikachu"&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="n"&gt;Test&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;void&lt;/span&gt; &lt;span class="n"&gt;testGraphqlWithNoVariables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"src/test/resources/graphql/pokemon-with-no-variable.graphql"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Now&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;string&lt;/span&gt;
        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;graphqlPayload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GraphqlTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parseGraphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Build&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;trigger&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
        &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prepareResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;graphqlPayload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Response Code Assertion"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;JsonNode&lt;/span&gt; &lt;span class="n"&gt;jsonNode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectMapper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;readTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pokemon"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;asText&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s2"&gt;"Pikachu"&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;



</description>
      <category>graphql</category>
      <category>java</category>
      <category>testing</category>
      <category>apitesting</category>
    </item>
    <item>
      <title>Test the Theme toggle app</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Wed, 29 May 2019 15:20:15 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/test-the-theme-toggle-app-4f6n</link>
      <guid>https://forem.com/email2vimalraj/test-the-theme-toggle-app-4f6n</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/email2vimalraj/toggle-theme-using-react-hooks-2ibe"&gt;article&lt;/a&gt; we’ve built an app with Theme toggling capability. In this article, let’s test that feature.&lt;/p&gt;

&lt;p&gt;I’ll be using &lt;a href="https://github.com/testing-library/react-testing-library"&gt;react-testing-library&lt;/a&gt; and &lt;a href="https://github.com/testing-library/jest-dom"&gt;jest-dom&lt;/a&gt; as a partner library for the &lt;code&gt;react-testing-library&lt;/code&gt; for leveraging custom DOM element matchers for Jest.&lt;/p&gt;

&lt;p&gt;Let’s install both the libraries as dev dependencies.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D react-testing-library jest-dom

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



&lt;p&gt;Since we used &lt;code&gt;create-react-app&lt;/code&gt;, there is a nice article to get started with running tests in their doc site &lt;a href="https://facebook.github.io/create-react-app/docs/running-tests"&gt;here&lt;/a&gt;. I highly recommend my readers to read through the doc once.&lt;/p&gt;

&lt;p&gt;As mentioned &lt;a href="https://facebook.github.io/create-react-app/docs/running-tests#option-2-react-testing-library"&gt;here&lt;/a&gt;, let’s create a &lt;code&gt;setupTests.js&lt;/code&gt; under the &lt;code&gt;src&lt;/code&gt; directory.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "react-testing-library/cleanup-after-each";
import "jest-dom/extend-expect";

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



&lt;ul&gt;
&lt;li&gt;The 1st import ensures the rendered component by &lt;code&gt;react-testing-library&lt;/code&gt; is removed after every test ran.&lt;/li&gt;
&lt;li&gt;The 2nd import let’s us use the &lt;code&gt;jest-dom&lt;/code&gt;‘s custom matchers mainly we use it for assertion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before writing our tests, let’s add an attribute &lt;code&gt;data-testid&lt;/code&gt; in the &lt;code&gt;header&lt;/code&gt; and &lt;code&gt;button&lt;/code&gt; component in our &lt;code&gt;App.js&lt;/code&gt; component as like follows:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header className="App-header" style={{ backgroundColor: theme.backgroundColor,
color: theme.color }} data-testid="header"&amp;gt;
  &amp;lt;button type="button"
    onClick={toggle} style={{ backgroundColor: theme.backgroundColor, color: theme.color, outline: 'none' }} data-testid="toggle-theme-btn" &amp;gt; 
...

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



&lt;p&gt;We’ll be using the &lt;code&gt;data-testid&lt;/code&gt; attribute to find the elements in our tests.&lt;/p&gt;

&lt;p&gt;Now let’s create a new test. Go and delete everything on &lt;code&gt;App.test.js&lt;/code&gt; and have the following test:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { render } from "react-testing-library";
import App from "./App";

test("renders with light mode default", () =&amp;gt; {
  const { getByTestId } = render(&amp;lt;App /&amp;gt;);
  expect(getByTestId("toggle-theme-btn")).toBeInTheDocument();
  expect(getByTestId("header")).toHaveStyle("background-color: white");
});

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



&lt;p&gt;In our 1st line, we render our &lt;code&gt;App&lt;/code&gt; component and then we assert whether there is a &lt;code&gt;Toggle theme&lt;/code&gt; button and the default &lt;code&gt;background color&lt;/code&gt; is &lt;code&gt;white&lt;/code&gt; using the respective &lt;code&gt;data-testid&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;Let’s run the test and see whether the run is success.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run test

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



&lt;p&gt;Hoorah!!! The test ran successfully!&lt;/p&gt;

&lt;p&gt;Now, let’s add another test to validate whether clicking on the toggle button changes the background color.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test("toggles the theme", () =&amp;gt; {
  const { getByTestId } = render(&amp;lt;App /&amp;gt;);
  const toggleBtn = getByTestId("toggle-theme-btn");
  fireEvent.click(toggleBtn);
  expect(getByTestId("header")).toHaveStyle("background-color: black");
  fireEvent.click(toggleBtn);
  expect(getByTestId("header")).toHaveStyle("background-color: white");
});

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



&lt;p&gt;Make sure you import &lt;code&gt;fireEvent&lt;/code&gt; from the &lt;code&gt;react-testing-library&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s see the run result. The newly added test failed &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2xnchDwe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f61f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2xnchDwe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f61f.png" alt="😟"&gt;&lt;/a&gt;. Why?&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✕ toggles the theme (29ms)

  ● toggles the theme

    expect(element).toHaveStyle()

    - Expected

    - background-color: black;
    + background-color: white;

      13 | const toggleBtn = getByTestId('toggle-theme-btn')
      14 | fireEvent.click(toggleBtn)
    &amp;gt; 15 | expect(getByTestId('header')).toHaveStyle('background-color: black')
         | ^
      16 | fireEvent.click(toggleBtn)
      17 | expect(getByTestId('header')).toHaveStyle('background-color: white')
      18 | })

      at Object.toHaveStyle (src/App.test.js:15:33)

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



&lt;p&gt;The execution stack trace says that the &lt;code&gt;background-color&lt;/code&gt; is still &lt;code&gt;white&lt;/code&gt;. That means after firing a &lt;code&gt;click&lt;/code&gt; event, the &lt;code&gt;localStorage&lt;/code&gt;‘s &lt;code&gt;setItem&lt;/code&gt; method is not properly triggered.&lt;/p&gt;

&lt;p&gt;To make this work, we should mock our &lt;code&gt;localStorage&lt;/code&gt; since the test doesn’t execute on the real browser and don’t have the &lt;code&gt;Storage&lt;/code&gt;. Now open up your &lt;code&gt;setupTests.js&lt;/code&gt; and append the following lines:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let store = {};

// Mock the `localStorage.getItem` method to return the value stored in the given key
jest.spyOn(Storage.prototype, "getItem").mockImplementation(key =&amp;gt; {
  return store[key];
});

// Mock the `localStorage.setItem` method to insert a given value into the given key
jest.spyOn(Storage.prototype, "setItem").mockImplementation((key, value) =&amp;gt; {
  return (store[key] = value + "");
});

// Mock the `localStorage.clear` method to clear the `store`
jest.spyOn(Storage.prototype, "clear").mockImplementation(() =&amp;gt; {
  store = {};
});

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



&lt;p&gt;Now let’s run our test and see the results. Still failing for the same reason. Let’s add some debug points with our famous &lt;code&gt;console.log&lt;/code&gt; statements in our &lt;code&gt;theme-context.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have added the following statement in our &lt;code&gt;toggle&lt;/code&gt; method within our &lt;code&gt;ThemeProvider&lt;/code&gt; function:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log("&amp;gt;&amp;gt;&amp;gt; clicked");

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



&lt;p&gt;Let’s see the run results and notice whether that statement is printed. Surprisingly, not!&lt;/p&gt;

&lt;p&gt;The reason is our &lt;code&gt;App&lt;/code&gt; component in the test is not wrapped with &lt;code&gt;ThemeProvider&lt;/code&gt;. We should wrap it. Let’s do that.&lt;/p&gt;

&lt;p&gt;Once you wrapped, your test must pass and the added &lt;code&gt;console.log&lt;/code&gt; statement should print twice!!!&lt;/p&gt;

&lt;p&gt;Great work. But do we need to wrap the &lt;code&gt;App&lt;/code&gt; component with &lt;code&gt;ThemeProvider&lt;/code&gt; in every single test. I heard you saying that’s a pain. But we have a solution for that too.&lt;/p&gt;

&lt;p&gt;So I’ve asked this question to &lt;a href="https://twitter.com/kentcdodds"&gt;Kent&lt;/a&gt; in &lt;a href="https://twitter.com/email2vimalraj/status/1131496659685220352"&gt;twitter here&lt;/a&gt;. And I got immediate responses.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yep. I recommend wrapping, but moving works too. Learn more about wrapping without the pain here: &lt;a href="https://testing-library.com/docs/react-testing-library/setup#custom-render"&gt;https://testing-library.com/docs/react-testing-library/setup#custom-render&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So as per the above, let’s create a test utility file to define our own render method. Create a file called &lt;code&gt;src/test-util.js&lt;/code&gt; and add the following:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { render } from "react-testing-library";
import { ThemeProvider } from "./theme-context";

const AllMyProviders = ({ children }) =&amp;gt; {
  return &amp;lt;ThemeProvider&amp;gt;{children}&amp;lt;/ThemeProvider&amp;gt;;
};

const MyCustomRender = (component, options) =&amp;gt;
  render(component, { wrapper: AllMyProviders, ...options });

// re-export everything from the `react-testing-library`
export * from "react-testing-library";

// export our custom render method
export { MyCustomRender as render };

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



&lt;p&gt;Let’s go to our test and make few changes:&lt;/p&gt;

&lt;p&gt;Replace&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { render, fireEvent } from "react-testing-library";

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



&lt;p&gt;with&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { render, fireEvent } from "./test-utils";

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



&lt;p&gt;And then, remove the &lt;code&gt;ThemeProvider&lt;/code&gt; wrapping for the &lt;code&gt;App&lt;/code&gt; component in all the tests. Now execute your test and see.&lt;/p&gt;

&lt;p&gt;The tests should run fine. That’s it for today. If you found this post useful, please hit like and share it.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reacttestinglibrary</category>
      <category>jest</category>
      <category>jestdom</category>
    </item>
    <item>
      <title>Toggle theme using React Hooks</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Tue, 28 May 2019 15:49:29 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/toggle-theme-using-react-hooks-2ibe</link>
      <guid>https://forem.com/email2vimalraj/toggle-theme-using-react-hooks-2ibe</guid>
      <description>&lt;p&gt;Originally published in my blog: &lt;a href="http://www.vimalselvam.com"&gt;http://www.vimalselvam.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was trying to implement the Dark mode to one of the application which I was working. Most of the examples available in Internet uses either &lt;code&gt;styled-components&lt;/code&gt; or any other &lt;code&gt;css-in-js&lt;/code&gt; concepts. The application which I’m working on doesn’t have the &lt;code&gt;css-in-js&lt;/code&gt; yet. So I want to keep it very simple. Hence, the very first thing that came up is to use React’s &lt;a href="https://reactjs.org/docs/context.html"&gt;Context&lt;/a&gt; API. Why Context? As per the react documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Context provides a way to pass data through the component tree without having to pass props down manually at every level.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, the definition is very self explanatory. We don’t have to pass the props to every component and down the component tree. Think of this maintains a global state.&lt;/p&gt;

&lt;p&gt;To create a context object, we should use React’s &lt;code&gt;createContext&lt;/code&gt; method and pass the default value to it (i.e., initial state).&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ThemeContext = React.createContext(initialState)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ThemeContext&lt;/code&gt; object contains a &lt;code&gt;ThemeContext.Provider&lt;/code&gt; component, so that the children component can consume the changes / state.&lt;/p&gt;

&lt;p&gt;We’ve pretty much covered the basic of what we need to do further. Let’s build the application which can toggle between light and dark mode. Please note that once I toggle to a particular mode, next time I visit the application, it should retain the same mode. That is, if I toggled to Light mode, next time I visit, it should display the application in Light mode only. So we’ll be using the &lt;code&gt;localStorage&lt;/code&gt; to persist the theme selected.&lt;/p&gt;

&lt;p&gt;Create a react app:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create-react-app my-app
cd my-app
npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open it in your favorite editor.&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;theme-context.js&lt;/code&gt; under &lt;code&gt;src&lt;/code&gt; directory.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const themes = {
  dark: {
    backgroundColor: 'black',
    color: 'white'
  },
  light: {
    backgroundColor: 'white',
    color: 'black'
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I’m keeping it simple. I’m maintaining two theme types &lt;code&gt;dark&lt;/code&gt; and &lt;code&gt;light&lt;/code&gt; with some simple background and foreground colors respectively. So if I toggled to &lt;code&gt;dark&lt;/code&gt; mode, then I should my page’s backgound color is changed to &lt;code&gt;black&lt;/code&gt; and foreground color to &lt;code&gt;white&lt;/code&gt; and if light, the other way around.&lt;/p&gt;

&lt;p&gt;Next, let me put in my initial state to put it in &lt;code&gt;createContext&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const initialState = {
  dark: false,
  theme: themes.light,
  toggle: () =&amp;gt; {}
}
const ThemeContext = React.createContext(initialState)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, let’s create a method which wraps all children with &lt;code&gt;ThemeContext.Provider&lt;/code&gt; component and export this method and the actual &lt;code&gt;ThemeContext&lt;/code&gt; object that we created just before.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ThemeProvider({ children }) {
  const [dark, setDark] = React.useState(false) // Default theme is light

  // On mount, read the preferred theme from the persistence
  React.useEffect(() =&amp;gt; {
    const isDark = localStorage.getItem('dark') === 'true'
    setDark(isDark)
  }, [dark])

  // To toggle between dark and light modes
  const toggle = () =&amp;gt; {
    const isDark = !dark
    localStorage.setItem('dark', JSON.stringify(isDark))
    setDark(isDark)
  }

  // Filter the styles based on the theme selected
  const theme = dark ? themes.dark : themes.light

  return (
    &amp;lt;ThemeContext.Provider value={{theme, dark, toggle}}&amp;gt;
      {children}
    &amp;lt;/ThemeContext.Provider&amp;gt;
  )
}

export { ThemeProvider }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So the final &lt;code&gt;theme-context.js&lt;/code&gt; look like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'

const themes = {
  dark: {
    backgroundColor: 'black',
    color: 'white'
  },
  light: {
    backgroundColor: 'white',
    color: 'black'
  }
}

const initialState = {
  dark: false,
  theme: themes.light,
  toggle: () =&amp;gt; {}
}
const ThemeContext = React.createContext(initialState)

function ThemeProvider({ children }) {
  const [dark, setDark] = React.useState(false) // Default theme is light

  // On mount, read the preferred theme from the persistence
  React.useEffect(() =&amp;gt; {
    const isDark = localStorage.getItem('dark') === 'true'
    setDark(isDark)
  }, [dark])

  // To toggle between dark and light modes
  const toggle = () =&amp;gt; {
    const isDark = !dark
    localStorage.setItem('dark', JSON.stringify(isDark))
    setDark(isDark)
  }

  const theme = dark ? themes.dark : themes.light

  return (
    &amp;lt;ThemeContext.Provider value={{ theme, dark, toggle }}&amp;gt;
      {children}
    &amp;lt;/ThemeContext.Provider&amp;gt;
  )
}

export { ThemeProvider, ThemeContext }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;index.js&lt;/code&gt; and wrap the &lt;code&gt;App&lt;/code&gt; component with our &lt;code&gt;ThemeProvider&lt;/code&gt;. So that the theme state can be shared with all the children available within &lt;code&gt;App&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;The modified &lt;code&gt;index.js&lt;/code&gt; look like:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import * as serviceWorker from './serviceWorker'
import { ThemeProvider } from './theme-context'

ReactDOM.render(
  &amp;lt;ThemeProvider&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/ThemeProvider&amp;gt;,
  document.getElementById('root')
)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s go to &lt;code&gt;App.js&lt;/code&gt; and add the following before the &lt;code&gt;return&lt;/code&gt; statement:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { theme, toggle, dark } = React.useContext(ThemeContext)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;useContext&lt;/code&gt; is the React’s Hook api which is equivalent to &lt;code&gt;ThemeContext.Consumer&lt;/code&gt; component. Read more about it &lt;a href="https://reactjs.org/docs/hooks-reference.html#usecontext"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then add a button before the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag to toggle the theme:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button
  type="button"
  onClick={toggle}
  style={{
    backgroundColor: theme.backgroundColor,
    color: theme.color,
    outline: 'none'
  }}
&amp;gt;
  Toggle to {!dark ? 'Dark' : 'Light'} theme
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now in the &lt;code&gt;header&lt;/code&gt; tag, add the following attribute:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;style={{ backgroundColor: theme.backgroundColor, color: theme.color }}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a look at your application (mostly it should be running at &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;). You can see the background color changed to &lt;code&gt;white&lt;/code&gt; and the foreground color in &lt;code&gt;black&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Click on the button to toggle between &lt;code&gt;Dark&lt;/code&gt; and &lt;code&gt;Light&lt;/code&gt; mode. You can close and re-open the tab or open a new tab of the same application, the theme mode is persisted.&lt;/p&gt;

&lt;p&gt;The entire code of &lt;code&gt;App.js&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import logo from './logo.svg'
import './App.css'
import { ThemeContext } from './theme-context'

function App() {
  const { theme, toggle, dark } = React.useContext(ThemeContext)

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;header
        className="App-header"
        style={{ backgroundColor: theme.backgroundColor, color: theme.color }}
      &amp;gt;
        &amp;lt;button
          type="button"
          onClick={toggle}
          style={{
            backgroundColor: theme.backgroundColor,
            color: theme.color,
            outline: 'none'
          }}
        &amp;gt;
          Toggle to {!dark ? 'Dark' : 'Light'} theme
        &amp;lt;/button&amp;gt;
        &amp;lt;img src={logo} className="App-logo" alt="logo" /&amp;gt;
        &amp;lt;p&amp;gt;
          Edit &amp;lt;code&amp;gt;src/App.js&amp;lt;/code&amp;gt; and save to reload.
        &amp;lt;/p&amp;gt;
        &amp;lt;a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        &amp;gt;
          Learn React
        &amp;lt;/a&amp;gt;
      &amp;lt;/header&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

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



&lt;p&gt;Demo:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/themecontexthookapi-uumsb"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>react</category>
      <category>contextapi</category>
      <category>createcontext</category>
      <category>hooks</category>
    </item>
    <item>
      <title>Form in Modal using React hooks – mistakes and lesson learnt</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Mon, 08 Apr 2019 14:28:50 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/form-in-modal-using-react-hooks-mistakes-and-lesson-learnt-19b4</link>
      <guid>https://forem.com/email2vimalraj/form-in-modal-using-react-hooks-mistakes-and-lesson-learnt-19b4</guid>
      <description>

&lt;p&gt;Recently, I’ve stumbled upon a problem while building a &lt;strong&gt;Form&lt;/strong&gt; in the &lt;strong&gt;Modal&lt;/strong&gt; box. I would like to share that experience and believe it might help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modal and Portals
&lt;/h2&gt;

&lt;p&gt;I wanted to create a modal which can show some content or the form. The best way to create a modal in React is to use &lt;a href="https://reactjs.org/docs/portals.html"&gt;Portal&lt;/a&gt;. Because, the modal should always be a individual component outside the DOM hierarchy. The Portal let you do this. Kindly read through the react’s documentation to know more about the Portal and the benefits. Additionally, this &lt;a href="https://www.nearform.com/blog/exploring-react-portals/"&gt;post&lt;/a&gt; might help you to understand better.&lt;/p&gt;

&lt;p&gt;So, we know what is Portal! Let’s build our &lt;code&gt;Modal&lt;/code&gt; component and render as a &lt;code&gt;Portal&lt;/code&gt;. I’m using &lt;a href="https://facebook.github.io/create-react-app/"&gt;create-react-app&lt;/a&gt; CLI tool to generate my react project. Before creating the portal, let’s make sure our &lt;code&gt;./public/index.html&lt;/code&gt; has the outer DOM hierarchy.&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;noscript&amp;gt;
    You need to enable JavaScript to run this app.
  &amp;lt;/noscript&amp;gt;
  &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;noscript&amp;gt;
    You need to enable JavaScript to run this app.
  &amp;lt;/noscript&amp;gt;
  &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div id="modal-root"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I’ve added another &lt;code&gt;div&lt;/code&gt; with the value of id attribute as &lt;code&gt;modal-root&lt;/code&gt;. That is where we render all our modals.&lt;/p&gt;

&lt;p&gt;Let’s create our &lt;code&gt;Modal&lt;/code&gt; component with &lt;code&gt;Portal&lt;/code&gt; support. I’ve created this under &lt;code&gt;components/modal/index.js&lt;/code&gt;&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect } from "react";
import { createPortal } from "react-dom";
import { StyledModal } from "./style";

// Creates a portal outside the DOM hierarchy
function Portal({ children }) {
  const modalRoot = document.getElementById("modal-root"); // A div with id=modal-root in the index.html
  const element = document.createElement("div"); // Create a div element which will be mounted within modal-root

  // useEffect bible: https://overreacted.io/a-complete-guide-to-useeffect/
  useEffect(() =&amp;gt; {
    modalRoot.appendChild(element);

    // cleanup method to remove the appended child
    return function cleanup() {
      modalRoot.removeChild(element);
    };
  });

  return createPortal(children, element);
}

// A modal component which will be used by other components / pages
function Modal({ children, toggle, open }) {
  return (
    &amp;lt;Portal&amp;gt;
      {open &amp;amp;&amp;amp; (
        &amp;lt;StyledModal.ModalWrapper onClick={toggle}&amp;gt;
          &amp;lt;StyledModal.ModalBody onClick={event =&amp;gt; event.stopPropagation()}&amp;gt;
            &amp;lt;StyledModal.CloseButton onClick={toggle}&amp;gt;
              &amp;amp;times;
            &amp;lt;/StyledModal.CloseButton&amp;gt;
            {children}
          &amp;lt;/StyledModal.ModalBody&amp;gt;
        &amp;lt;/StyledModal.ModalWrapper&amp;gt;
      )}
    &amp;lt;/Portal&amp;gt;
  );
}

export default Modal;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;Portal&lt;/code&gt; method creates the portal and uses the &lt;code&gt;useEffect&lt;/code&gt; hook to append the &lt;code&gt;div&lt;/code&gt; element to the &lt;code&gt;modal-root&lt;/code&gt; element and removes while &lt;code&gt;unmounting&lt;/code&gt;. Here is the problem I faced, but wait till we uncover the issue.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;StyledModal&lt;/code&gt; is the styled component and the code is below (created under &lt;code&gt;/components/modal/style.js&lt;/code&gt;):&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import styled from "styled-components";

const ModalWrapper = styled.div`
  position: fixed;
  z-index: 1;
  padding-top: 100px;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgba(0, 0, 0, 0.4);
`;

const ModalBody = styled.div`
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 30%;
`;

const CloseButton = styled.span`
  color: #aaaaaa;
  float: right;
  font-size: 28px;
  font-weight: bold;

  &amp;amp;:hover,
  &amp;amp;:focus {
    color: #000;
    text-decoration: none;
    cursor: pointer;
  }
`;

export const StyledModal = {
  ModalWrapper,
  ModalBody,
  CloseButton
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you notice our &lt;code&gt;Modal&lt;/code&gt; component, there are 3 props:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open: A boolean prop to decide whether to show the modal or not.&lt;/li&gt;
&lt;li&gt;toggle: A method prop to toggle &lt;code&gt;open&lt;/code&gt; from &lt;code&gt;true&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; or vice-versa.&lt;/li&gt;
&lt;li&gt;children: A children component to render within modal. This is usually a modal content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To toggle the &lt;code&gt;Modal's&lt;/code&gt; state, let’s create a new custom hook and call it as &lt;code&gt;useToggle&lt;/code&gt;. I’m creating &lt;code&gt;useToggle.js&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useCallback } from "react";

// Toggles between true or false
function useToggle(initialValue = false) {
  const [toggle, setToggle] = useState(initialValue);

  return [toggle, useCallback(() =&amp;gt; setToggle(status =&amp;gt; !status), [])];
}

export default useToggle;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this user can toggle between &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. This will be used in our &lt;code&gt;App&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Let’s rewrite our &lt;code&gt;App&lt;/code&gt; component in the &lt;code&gt;index.js&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [open, setOpen] = useToggle(false);

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;h1&amp;gt;Hello CodeSandbox&amp;lt;/h1&amp;gt;
      &amp;lt;button type="button" onClick={() =&amp;gt; setOpen()}&amp;gt;
        Open Modal
      &amp;lt;/button&amp;gt;

      {open &amp;amp;&amp;amp; (
        &amp;lt;Modal open={open} toggle={setOpen}&amp;gt;
          &amp;lt;h1&amp;gt;Hello Modal&amp;lt;/h1&amp;gt;
        &amp;lt;/Modal&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;useToggle&lt;/code&gt; hook gives the state of &lt;code&gt;toggle&lt;/code&gt; through a parameter called &lt;code&gt;open&lt;/code&gt; and the &lt;code&gt;setOpen&lt;/code&gt; let you to toggle the value of the &lt;code&gt;open&lt;/code&gt;. The rest of the code is self-explanatory.&lt;/p&gt;

&lt;p&gt;When you run, you don’t see any problem. Great! We’ve built the Modal which shows the heading. Let’s extend it and add a form to our modal component with one input box.&lt;/p&gt;

&lt;p&gt;I’ve modified my &lt;code&gt;App&lt;/code&gt; component with an &lt;code&gt;input&lt;/code&gt; element under the &lt;code&gt;form&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
  const [open, setOpen] = useToggle(false);
  const [username, setUsername] = useState("");

  const onChangeUsername = e =&amp;gt; setUsername(e.target.value);

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;h1&amp;gt;Hello CodeSandbox&amp;lt;/h1&amp;gt;
      &amp;lt;button type="button" onClick={() =&amp;gt; setOpen()}&amp;gt;
        Open Modal
      &amp;lt;/button&amp;gt;

      {open &amp;amp;&amp;amp; (
        &amp;lt;Modal open={open} toggle={setOpen}&amp;gt;
          &amp;lt;h1&amp;gt;Hello Modal&amp;lt;/h1&amp;gt;

          &amp;lt;form onSubmit={e =&amp;gt; e.preventDefault()}&amp;gt;
            &amp;lt;input
              type="text"
              name="username"
              value={username}
              onChange={e =&amp;gt; onChangeUsername(e)}
            /&amp;gt;
          &amp;lt;/form&amp;gt;
        &amp;lt;/Modal&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now run the code and open up the modal. Try to enter more than one character in the displayed input box. Gosh, it is broken!!! For every character, the modal re-renders. Did you see that?&lt;/p&gt;

&lt;p&gt;Okay, how to fix that now? I’ve spent ample of time to understand the issue. With some help of reddit users and &lt;code&gt;useEffect&lt;/code&gt; &lt;a href="https://overreacted.io/a-complete-guide-to-useeffect/"&gt;bible&lt;/a&gt;, I’ve found an issue in our &lt;code&gt;Portal&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;Portal&lt;/code&gt; component, we’ve to put the &lt;code&gt;div&lt;/code&gt; element into the state and add &lt;code&gt;modal-root&lt;/code&gt; and &lt;code&gt;div&lt;/code&gt; as dependencies for the &lt;code&gt;useEffect&lt;/code&gt;. So that it doesn’t re-render. Let’s do this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Portal({ children }) {
  const modalRoot = document.getElementById("modal-root"); // A div with id=modal-root in the index.html
  const [element] = useState(document.createElement("div")); // Create a div element which will be mounted within modal-root

  // useEffect bible: https://overreacted.io/a-complete-guide-to-useeffect/
  useEffect(() =&amp;gt; {
    modalRoot.appendChild(element);

    // cleanup method to remove the appended child
    return function cleanup() {
      modalRoot.removeChild(element);
    };
  }, [modalRoot, element]);

  return createPortal(children, element);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now run, and try the same which caused the problem. Voila! now it worked.&lt;/p&gt;

&lt;p&gt;So always to remember, make sure &lt;code&gt;useEffect&lt;/code&gt; has the dependencies set properly to avoid re-rendering.&lt;/p&gt;

&lt;p&gt;The sample code sandbox can be found here:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/1z2p4wqyjq"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;I hope my experience could help someone. If you like this article, kindly hit the &lt;strong&gt;Like&lt;/strong&gt; button and &lt;strong&gt;Share&lt;/strong&gt;.&lt;/p&gt;


</description>
      <category>react</category>
      <category>customhooks</category>
      <category>form</category>
      <category>modal</category>
    </item>
    <item>
      <title>React Hooks: Lift up / pass down state using useContext and useReducer</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Wed, 13 Mar 2019 23:45:39 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/react-hooks-lift-up--pass-down-state-using-usecontext-and-usereducer-5ai0</link>
      <guid>https://forem.com/email2vimalraj/react-hooks-lift-up--pass-down-state-using-usecontext-and-usereducer-5ai0</guid>
      <description>&lt;p&gt;This post was published in my &lt;a href="http://vimalselvam.com" rel="noopener noreferrer"&gt;Blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've ran into a situation where I had many child and sibling components trying to share the state between them. Earlier, I used &lt;code&gt;prop&lt;/code&gt; to send a method to share the updated states between the components. At one point of time, the number of props kept increasing and I hated that.&lt;/p&gt;

&lt;p&gt;Then came a &lt;code&gt;context&lt;/code&gt; based approach to store the state in a global store and share it across. But even with the &lt;code&gt;context&lt;/code&gt; API, you had to have a &lt;code&gt;render props&lt;/code&gt; to consume the stored state from the global &lt;code&gt;context&lt;/code&gt;. You will soon realise that your component becomes a nested, non-maintainable and haunting to look back.&lt;/p&gt;

&lt;p&gt;Now this post talks about how we can leverage the latest React's &lt;code&gt;hooks&lt;/code&gt; concepts to achieve the same with a cleaner code.&lt;/p&gt;

&lt;p&gt;Let's first build the sample UI with some child &amp;amp; sibling components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's UI
&lt;/h2&gt;

&lt;p&gt;Head on to the &lt;a href="https://codesandbox.io" rel="noopener noreferrer"&gt;CodeSandbox&lt;/a&gt; to quickly experiment. Make sure that you create a &lt;code&gt;React&lt;/code&gt; code sandbox.&lt;/p&gt;

&lt;p&gt;Replace the &lt;code&gt;index.js&lt;/code&gt; with the following:&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="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;ReactDOM&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-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&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="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Lift up / Pass down state&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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;UserList&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;AddGenderToUser&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;AddAgeToUser&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Vimalraj Selvam&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Edit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Bhuvaneswari Vimalraj&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Edit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AddGenderToUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add gender to &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Age&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AddAgeToUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add Age to &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&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="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&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;(&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="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I've 3 child components to parent &lt;code&gt;App&lt;/code&gt; component: &lt;code&gt;UserList&lt;/code&gt;, &lt;code&gt;AddGenderToUser&lt;/code&gt; and &lt;code&gt;AddAgeToUser&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is very simple example. So don't think much about the usecase of this application.&lt;/p&gt;

&lt;p&gt;I wanted to show the &lt;code&gt;AddGenderToUser&lt;/code&gt; component only when the &lt;code&gt;Edit&lt;/code&gt; button for a particular user is clicked and update the title of the of the component with selected username.&lt;/p&gt;

&lt;p&gt;The same thing goes for &lt;code&gt;AddAgeToUser&lt;/code&gt; component, upon clicking the &lt;code&gt;Add Age&lt;/code&gt; button from the &lt;code&gt;AddGenderToUser&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;First, let create a initial state of the application when no user is selected.&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;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create our reducer method to perform different actions. The actions which I can think of are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update the user&lt;/li&gt;
&lt;li&gt;Set the gender for the current user&lt;/li&gt;
&lt;li&gt;Set the age for the current user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's put this in a &lt;code&gt;reducer&lt;/code&gt; function:&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;UPDATE_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_USER&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;SET_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;SET_GENDER&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;SET_AGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SET_AGE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_USER&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;age&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="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;SET_GENDER&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&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;action&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;age&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="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;SET_AGE&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&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;state&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;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&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;initialState&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;Our reducer method is very simple. It takes values from the &lt;code&gt;action&lt;/code&gt; parameter and sets it to current state.&lt;/p&gt;

&lt;p&gt;Now let's use this reducer function in our parent &lt;code&gt;App&lt;/code&gt; component using &lt;code&gt;useReducer&lt;/code&gt; hook from the react. So that we can consume the properties of reducer through the &lt;code&gt;context&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's add the below line just before the &lt;code&gt;return&lt;/code&gt; statement of &lt;code&gt;App&lt;/code&gt; 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="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;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;user&lt;/code&gt; is the current state and &lt;code&gt;dispatch&lt;/code&gt; is the method through which we trigger various actions defined on the reducer. To do that, we have to pass the &lt;code&gt;dispatch&lt;/code&gt; method to down the line and also if any updates happens at the &lt;code&gt;state&lt;/code&gt; object, the parent / other children of parent should also be aware about.&lt;/p&gt;

&lt;p&gt;To achieve the above objective, we have to leverage &lt;code&gt;context&lt;/code&gt; API from react to store our state and dispatch.&lt;/p&gt;

&lt;p&gt;Let's initialize the &lt;code&gt;context&lt;/code&gt; with the following line. This line should be before your &lt;code&gt;App&lt;/code&gt; function (it really doesn't matter).&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;MyContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createContext&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've initialized the context with null. We've to put our state and dispatch into the context. To do that, let's edit our &lt;code&gt;App&lt;/code&gt; component by wrapping all the childrens with &lt;code&gt;context's&lt;/code&gt; provider. The updated &lt;code&gt;App&lt;/code&gt; component should look like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="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;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserList&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="si"&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;username&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddGenderToUser&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="si"&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddAgeToUser&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now we can access the &lt;code&gt;user&lt;/code&gt; state and the corresponding &lt;code&gt;dispatch&lt;/code&gt; method down the line. Also, I've added a conditional rendering of few child elements based on the &lt;code&gt;user&lt;/code&gt; state properties &lt;code&gt;username&lt;/code&gt; &amp;amp; &lt;code&gt;gender&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's update our &lt;code&gt;UserList&lt;/code&gt; component to trigger the &lt;code&gt;UPDATE_USER&lt;/code&gt; action upon clicking on &lt;code&gt;Edit&lt;/code&gt; button for a particular user. To do that, we've to get the &lt;code&gt;dispatch&lt;/code&gt; method from the &lt;code&gt;context&lt;/code&gt; using &lt;code&gt;useContext&lt;/code&gt; hook from React.&lt;/p&gt;

&lt;p&gt;The rewritten &lt;code&gt;UserList&lt;/code&gt; component:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Vimalraj Selvam&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
          &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UPDATE_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Vimalraj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Edit
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Removed for brevity */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're dispatching &lt;code&gt;UPDATE_USER&lt;/code&gt; action and sending the &lt;code&gt;username&lt;/code&gt; along with to update the property of the state. Now when you click on the &lt;code&gt;Edit&lt;/code&gt; button for a particular user, you can see the &lt;code&gt;AddGenderToUser&lt;/code&gt; component appears. But we still don't see the username in the appeared component. Let's fix that!&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AddGenderToUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="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;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Add gender to &lt;span class="si"&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;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SET_GENDER&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;??&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Add Age
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're getting the current &lt;code&gt;user&lt;/code&gt; state and &lt;code&gt;dispatch&lt;/code&gt; method. We extract the &lt;code&gt;username&lt;/code&gt; property to display in a title and trigger &lt;code&gt;SET_GENDER&lt;/code&gt; action upon clicking on &lt;code&gt;Add Age&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;You can repeat the same for the &lt;code&gt;AddAgeToUser&lt;/code&gt; function as well.&lt;/p&gt;

&lt;p&gt;The completed version is available in the code sandbox, please feel free to view here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/s/pw5zlq8zj0?fontsize=14" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcodesandbox.io%2Fstatic%2Fimg%2Fplay-codesandbox.svg" alt="Edit Lift up / pass down state"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the code sandbox, I've slightly updated the &lt;code&gt;App&lt;/code&gt; component to show the details once the age is updated.&lt;/p&gt;

&lt;p&gt;If this post helped you, please hit like and share.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reacthooks</category>
      <category>usereducer</category>
      <category>usecontext</category>
    </item>
    <item>
      <title>Dynamic form fields using React with hooks</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Wed, 13 Mar 2019 14:11:12 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/dynamic-form-fields-using-react-35ci</link>
      <guid>https://forem.com/email2vimalraj/dynamic-form-fields-using-react-35ci</guid>
      <description>

&lt;p&gt;I'm trying to create a form where I'm letting user to add as many number of input fields and also giving an ability to remove any particular added input field.&lt;/p&gt;

&lt;p&gt;Adding a field works fine, however, the remove always removes the last field, not the one which I wanted to remove.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFields&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;value&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;setFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleAdd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&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="nx"&gt;setFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleRemove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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="nx"&gt;setFields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s2"&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="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello CodeSandbox&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;handleAdd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        +
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fields&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;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`${field}-${idx}`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
              &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s2"&gt;"Enter text"&lt;/span&gt;
              &lt;span class="na"&gt;onChange=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&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="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt; &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;handleRemove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              X
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The code sandbox is here: &lt;a href="https://codesandbox.io/s/q555kp8jj?fontsize=14"&gt;https://codesandbox.io/s/q555kp8jj?fontsize=14&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same thing works with Class component, here is the code sandbox: &lt;a href="https://codesandbox.io/s/wznq443xl?fontsize=14"&gt;https://codesandbox.io/s/wznq443xl?fontsize=14&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To reproduce the issue, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add some text in the 1st input text field&lt;/li&gt;
&lt;li&gt;Add a new text field by clicking on &lt;strong&gt;+&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;X&lt;/strong&gt; button next to the 1st text field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see that the above step removes the 2nd field, not the 1st field.&lt;/p&gt;

&lt;p&gt;When I inspect, the &lt;code&gt;fields&lt;/code&gt; state is properly updating when I click remove button. Kindly help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: The issue has been solved after making the &lt;code&gt;input&lt;/code&gt; to &lt;strong&gt;controlled&lt;/strong&gt; component. Thanks to a reddit user to find the issue. Refer more &lt;a href="https://www.reddit.com/r/reactjs/comments/b0mo2d/help_needed_dynamic_form_fields_using_react_with/eigmygl/?context=3"&gt;here&lt;/a&gt;&lt;/p&gt;


</description>
      <category>react</category>
      <category>reacthooks</category>
    </item>
    <item>
      <title>Python: Module Management</title>
      <dc:creator>Vimalraj Selvam</dc:creator>
      <pubDate>Mon, 04 Mar 2019 10:19:34 +0000</pubDate>
      <link>https://forem.com/email2vimalraj/python-module-management-53f</link>
      <guid>https://forem.com/email2vimalraj/python-module-management-53f</guid>
      <description>

&lt;p&gt;Originally published in my &lt;a href="http://www.vimalselvam.com/2019/03/04/python-module-management/"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This post is the continuation of my previous post: &lt;a href="https://dev.to/email2vimalraj/python-package-management-with-pipenv-44kh-temp-slug-7990359"&gt;Python Package Management with Pipenv&lt;/a&gt;. I’ve package / dependency management in place, now I would like to setup the folder structure and get the scripts executed.&lt;/p&gt;

&lt;p&gt;My problem statement is that I don’t have any main script which can call any modules to trigger. Time to time, I execute any scripts from any folder individually and I should not have any hard dependencies with any file. Let me show you an example which can easily explain my problem.&lt;/p&gt;

&lt;p&gt;Consider the following folder structure I have in place now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i1.wp.com/www.vimalselvam.com/wp-content/uploads/2019/03/python-demo-project-structure.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XJAzerDD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/www.vimalselvam.com/wp-content/uploads/2019/03/python-demo-project-structure.png%3Fresize%3D179%252C300" alt="Folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;__init__.py&lt;/code&gt; is the special file which helps python to treat the folders / files as module. For example, the &lt;code&gt;__init__.py&lt;/code&gt; file in the &lt;code&gt;common/&lt;/code&gt; directory makes it as a module, so that user can import this as a module anywhere. And the content of the &lt;code&gt;__init__.py&lt;/code&gt; file is just empty.&lt;/p&gt;

&lt;p&gt;The content of my &lt;code&gt;constant.py&lt;/code&gt; is very simple:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENDPOINT = "http://vimalselvam.com"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and the &lt;code&gt;start.py&lt;/code&gt; in the &lt;code&gt;src/datastore/&lt;/code&gt; directory:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import common.constant as constant

def run():
    print(constant.ENDPOINT)

if __name__ == " __main__":
    run()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just by looking at the above code, you think there is no problem in executing, right? That was wrong. Let’s execute and see what’s happening:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ pipenv run python src/datastore/start.py
Traceback (most recent call last):
  File "src/datastore/start.py", line 1, in &amp;lt;module&amp;gt;
    import common.constant as constant
ModuleNotFoundError: No module named 'common'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What happened! The problem is that Python doesn’t resolve the module dependencies if you execute the file which is not relative to the current directory. So you’ve to execute the &lt;code&gt;start.py&lt;/code&gt; file as a module. Let’s do that:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ pipenv run python -m src.datastore.start
http://vimalselvam.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Gotcha! I’ve spent some time to figure this out and hence this as a post. If you found this useful, please like and share.&lt;/p&gt;


</description>
      <category>python</category>
      <category>modulemanagement</category>
      <category>pipenv</category>
      <category>pipfile</category>
    </item>
  </channel>
</rss>
