<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wing</title>
    <description>The latest articles on DEV Community by Wing (@wingpuah).</description>
    <link>https://dev.to/wingpuah</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%2F194049%2F26f35849-4cf7-4b9b-b1db-87e9525498d2.jpeg</url>
      <title>DEV Community: Wing</title>
      <link>https://dev.to/wingpuah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wingpuah"/>
    <language>en</language>
    <item>
      <title>Applying publisher subscriber design pattern in javascript</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sun, 30 Jan 2022 16:01:45 +0000</pubDate>
      <link>https://dev.to/wingpuah/applying-publisher-subscriber-design-pattern-in-javascript-jeb</link>
      <guid>https://dev.to/wingpuah/applying-publisher-subscriber-design-pattern-in-javascript-jeb</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;MeowLand is ruled by King Whiskers. Recently, MeowLand has experiencing rapid growth. One night, King Whiskers decide that he needs to upgrade the knowledge and skills of the catizens of MeowLand in order to improve the CDP and sustain the growth of the population. He aims to do that by regularly disseminating information from the palace library.&lt;/p&gt;

&lt;p&gt;However, he knows that his catizens are busy cats and he does not want to overwhelm them with irrelavant news.&lt;/p&gt;

&lt;p&gt;The catizens are largely distributed across this industry:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mouse hunter&lt;/li&gt;
&lt;li&gt;Bird hunter&lt;/li&gt;
&lt;li&gt;Comedian&lt;/li&gt;
&lt;li&gt;Glam Vloggers&lt;/li&gt;
&lt;li&gt;Daredevils&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Looking at the problem, we can form a few premises.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Information that needs to be pushed&lt;/li&gt;
&lt;li&gt;Catizens will receive the information&lt;/li&gt;
&lt;li&gt;Information will be disperse based on the topic of interest relevant to the catizen&lt;/li&gt;
&lt;li&gt;Catizens can have more than one topic of interest&lt;/li&gt;
&lt;li&gt;Catizens can change interest and stop update from a particular topic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this problem, we will look at the &lt;strong&gt;publisher/subscriber&lt;/strong&gt; pattern&lt;/p&gt;

&lt;h2&gt;
  
  
  Publisher/Subscriber Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Publisher/Subscriber&lt;/strong&gt; pattern or the PubSub pattern for short, is a behavioral design pattern. As it's name suggest, it is a design pattern for a subject (Publisher) to notify changes to a list of observers (Subscriber).&lt;/p&gt;

&lt;p&gt;Perhaps, you have use the &lt;a href="https://rxjs.dev/guide/overview"&gt;RxJS library&lt;/a&gt;, and the term Observer seems familiar. You are right, the PubSub design pattern is a variation of of the &lt;a href="https://sourcemaking.com/design_patterns/observer"&gt;Observer pattern &lt;/a&gt; and RxJS utilises this pattern. Another common implementation of the observer pattern will be the &lt;code&gt;connect&lt;/code&gt; method in Redux.&lt;/p&gt;

&lt;blockquote&gt;

&lt;em&gt;Observer pattern define by GoF&lt;/em&gt;


Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.


-- &lt;em&gt;Design Patterns: Elements of Reusable Object-Oriented Software &lt;/em&gt;
&lt;/blockquote&gt;

&lt;p&gt;The benefit of implementing an Observer pattern is that two objects are loosely coupled and minimize interdependency between objects. However, because of decoupling, it can sometimes become difficult to ensure that the various parts of the application is working as part of the application can crash without affecting other part of the system.&lt;/p&gt;

&lt;p&gt;There is a small difference between the two patterns. For the PubSub pattern, there is a topic/event channel that sits between the publisher and the subscriber. This event system allows the subscriber to be notify of specific events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YzJOrRfh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1584189742/blog/2020/03/pubsub/Observer_pattern.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YzJOrRfh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1584189742/blog/2020/03/pubsub/Observer_pattern.jpg" width="835" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;Now that we have the overview of this design pattern, we will create the code for King Whisksers.&lt;/p&gt;

&lt;p&gt;Firstly, we will create the &lt;code&gt;Publisher&lt;/code&gt; class, which will register the subscribers and publish events to the subscribers. For the method &lt;code&gt;subscribe&lt;/code&gt;, the argument &lt;code&gt;event&lt;/code&gt; will be the key that the subscribers is listening to. In our case, a bird hunter will need to listen to &lt;code&gt;climb trees&lt;/code&gt; events.&lt;/p&gt;

&lt;p&gt;When King Whiskers will like to publish a &lt;code&gt;climb trees&lt;/code&gt; news, we will find the &lt;code&gt;climb trees&lt;/code&gt; key in subscribers and invoke the callback register during subscription.&lt;/p&gt;

&lt;p&gt;To simplify unsubscription, we will pass the &lt;code&gt;unsubscribe&lt;/code&gt; method to be register with the subscribers. In a perfect world, we will create an advanced PubSub which will handle the unsubscripton through the event and the topic but that will introduce a more abstracted code.&lt;/p&gt;

&lt;blockquote&gt;
To understand how to implement a PubSub with nested arguments, check out Jack Lawson's Mediator.js. 

&lt;strong&gt;Read&lt;/strong&gt;: &lt;a href="http://thejacklawson.com/Mediator.js/"&gt;Mediator.js&lt;/a&gt;

&lt;/blockquote&gt;

&lt;p&gt;PubSub.js&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;class&lt;/span&gt; &lt;span class="nx"&gt;PubSub&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;subscribe&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="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&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="o"&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&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="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;subscribers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&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;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;subscribers&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="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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="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;publish&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="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="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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&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="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribers&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="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subscriberCallback&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;subscriberCallback&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Next, we will create our &lt;code&gt;Cat&lt;/code&gt; class. Do note that, as mention above, in the perfect world, our &lt;code&gt;Cat&lt;/code&gt; class will not need to handle subscription.&lt;/p&gt;

&lt;p&gt;Cat.js&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;class&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;interests&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&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="p"&gt;{};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;addUnsubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;method&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;Then, we will set up the PubSub and test if everything is working based on the 5 premises mention above.&lt;/p&gt;


&lt;br&gt;
catDomPubSub.js&lt;br&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catDomPubSub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;PubSub&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;cat1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Midnight&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;climb trees&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hunt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weather&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;cat2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bear&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;humour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weather&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;camera skills&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;cat3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Smokey&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hunt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;camera skills&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;allCat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cat1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cat2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cat3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;allCat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;singleCat&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interests&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;singleCat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;interests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interest&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;unsubscribe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catDomPubSub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;printInterestReceived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interest&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="nx"&gt;allCat&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;addUnsubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interest&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="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;printInterestReceived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;interest&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; has received information for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;interest&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;data&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;span class="nx"&gt;catDomPubSub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;climb trees&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn coordination&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;catDomPubSub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weather&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Might rain tomorrow, stay indoors!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;catDomPubSub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hunt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Predicted migration of house rats tomorrow, stay alert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;cat1&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="nx"&gt;hunt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;catDomPubSub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hunt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sharpen your claws&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;p&gt;If we run this code, we will see the following.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Midnight has received information for climb trees: Learn coordination

Midnight has received information for weather: Might rain tomorrow, stay indoors!
Bear has received information for weather: Might rain tomorrow, stay indoors!

Midnight has received information for hunt: Predicted migration of house rats tomorrow, stay alert
Smokey has received information for hunt: Predicted migration of house rats tomorrow, stay alert

Smokey has received information for hunt: Predicted migration of house rats tomorrow, stay alert
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Because Midnight unsubscribes from &lt;code&gt;hunt&lt;/code&gt;, the last publish of hunt will not show Midnight.&lt;/p&gt;

&lt;p&gt;Finally, we can show our product to King Whiskers.&lt;/p&gt;

&lt;p&gt;This is the gist of a simple example of the PubSub model.&lt;/p&gt;

&lt;p&gt;Is this consider completed? No, because we did not store the notifications in each individual &lt;code&gt;Cat&lt;/code&gt;. For example, the cat could be a level of each skillsets that you are keeping track of based on the publications they receive. Upon each update, they will improve their experience require to level up. Till next time, we will explore more alternatives with the &lt;strong&gt;Observer&lt;/strong&gt; and &lt;strong&gt;PubSub&lt;/strong&gt; design pattern.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>patterns</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Cheat sheet to common React terms</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sun, 30 Jan 2022 16:00:35 +0000</pubDate>
      <link>https://dev.to/wingpuah/cheat-sheet-to-common-react-terms-1kn3</link>
      <guid>https://dev.to/wingpuah/cheat-sheet-to-common-react-terms-1kn3</guid>
      <description>&lt;p&gt;React.js is a Javsacript library that is created by Facebook. The benefits of using react is enabling code reusability, faster development time and higher web performance. If you remember the days of implementing AJAX for page components update, you will find that react makes creating dynamic UI a breeze.&lt;/p&gt;

&lt;p&gt;The popularity of React among developers and enterprise as the top frontend framework remains almost unchallenged by other popular frontend framework like angular and vue.&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%2Fres.cloudinary.com%2Fthegeekwing%2Fimage%2Fupload%2Fv1584773446%2Fblog%2F2020%2F03%2Freactjs%2Fnpm-frontend-trend.jpg" 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%2Fres.cloudinary.com%2Fthegeekwing%2Fimage%2Fupload%2Fv1584773446%2Fblog%2F2020%2F03%2Freactjs%2Fnpm-frontend-trend.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are just starting to venture into frontend web development, React is a good place to look onto of your Javascript toolbox. Here is a quick cheat sheet to introduce you to the world of React.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;To understand any React codebase, you need to think in terms of components. Think of the web as many rectangles. Even for irregular shapes, you can draw rectangles around them. These rectangles might overlap each other, have a certain padding or margin around them, but they are all certainly derive from a rectangle.&lt;/p&gt;

&lt;p&gt;If you want to see the components in actions, the React documentation has a great breakdown on components-based thinking. Next, we will look at the two common types of React components.&lt;/p&gt;

&lt;blockquote&gt;



&lt;strong&gt;Read&lt;/strong&gt;: &lt;a href="https://reactjs.org/docs/thinking-in-react.html" rel="noopener noreferrer"&gt;Thinking in React&lt;/a&gt;


-- &lt;em&gt;React documentation&lt;/em&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Class
&lt;/h2&gt;

&lt;p&gt;Previously, a &lt;code&gt;class&lt;/code&gt; component in React is one of the few way that you can hold state in your components. In a class component, there will be lifecycle methods to determine if the component should update the rendered elements.&lt;/p&gt;

Commonly used lifecycle methods are:  
&lt;code&gt;componentDidMount&lt;/code&gt;: invoked when the component is mounted on to the tree
&lt;code&gt;componentDidUpdate&lt;/code&gt;: invoked immediately after the update occur
&lt;code&gt;componentWillUnmount&lt;/code&gt;: invoked immediately before the component is unmounted. Invalidating timeres, canceling network request or cleaning up subscription is done in this method


&lt;p&gt;A class component with state, props (more on that later) and methods will look something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CatFeeder&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;batteryLife&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;feedCats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;componentDidUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&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="k"&gt;this&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;batteryLife&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;batteryLife&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="k"&gt;this&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;batteryLife&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;switchOff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;feedCats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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="na"&gt;batteryLife&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;batteryLife&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&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;catToFeed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;ultimate&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="nx"&gt;feeder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Currently&lt;/span&gt; &lt;span class="nx"&gt;feeding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;catToFeed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="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;h2&gt;
  
  
  Functional components
&lt;/h2&gt;

&lt;p&gt;As we can see from above, a class component of React can become verbose quickly with a lot of boilerplate code. Another type of component, we can write is &lt;code&gt;functional components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As the name suggest, we will write functional components as a function declaration or a fat arrow function. Previously, functional components are pure presentational components that do not hold state. However, since the introduction of React hooks (e.g. &lt;code&gt;useState&lt;/code&gt; &amp;amp; &lt;code&gt;useEffect&lt;/code&gt; in the example below), we are now able to hold state in the functional components. The community at large, seems to have move to favour more in functional components and hooks over class components.&lt;/p&gt;

&lt;p&gt;A function compoennt with state, props, will look something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CatFeeder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;switchOff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;catToFeed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;batteryLife&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBatteryLife&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;feedCats&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;feedCats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setBatteryLife&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevBatteryLife&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;prevBatteryLife&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;batteryLife&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;switchOff&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;batteryLife&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;ultimate&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="nx"&gt;feeder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Currently&lt;/span&gt; &lt;span class="na"&gt;feeding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;catToFeed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hooks, state, and props
&lt;/h2&gt;

&lt;p&gt;At this point, you might be wondering, what exactly is the difference among hooks, state and props. These are the fundamental building block of React. In fact, I will go further to say that, on most web app, besides building the interface, you are mainly managing the browser state, either persistent (browser storage) or non persistent (web memory).&lt;/p&gt;

&lt;h3&gt;
  
  
  State and props
&lt;/h3&gt;

&lt;p&gt;As the name mention, state is a piece of state held by the component. It is seen in &lt;code&gt;this.state&lt;/code&gt; in the &lt;code&gt;class&lt;/code&gt; component and &lt;code&gt;useState&lt;/code&gt; in the functional components. React employs a unidirectional data flow. A state in a parent component can be passed down as &lt;code&gt;props&lt;/code&gt; in the child component.&lt;/p&gt;

&lt;p&gt;Let's imagine that we composite our CatFeeder as part of the component of the whole CatFeederMachine. The parent component &lt;code&gt;CatFeederMachine&lt;/code&gt; will holds the &lt;code&gt;isOn&lt;/code&gt; state. The methods to control the &lt;code&gt;isOn&lt;/code&gt; state is defined in the parent component and pass down to the child components as props.&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%2Fres.cloudinary.com%2Fthegeekwing%2Fimage%2Fupload%2Fv1584778134%2Fblog%2F2020%2F03%2Freactjs%2Freact-state-props.jpg" 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%2Fres.cloudinary.com%2Fthegeekwing%2Fimage%2Fupload%2Fv1584778134%2Fblog%2F2020%2F03%2Freactjs%2Freact-state-props.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hooks
&lt;/h3&gt;

&lt;p&gt;Now that you understand the difference between &lt;code&gt;state&lt;/code&gt; and &lt;code&gt;props&lt;/code&gt;, we can start to grasp the concept of &lt;code&gt;hooks&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hooks greatly simplify our component logic and promote reusability of the stateful logic.&lt;/p&gt;

Commonly used hooks are 
&lt;code&gt;useState&lt;/code&gt;: store state. As seen above, a useState hook destruct to [state, setState]
&lt;code&gt;useEffect&lt;/code&gt;: trigger sideEffect when there is a change. Setting state in useEffect might sometimes cause some rendering issue.
&lt;code&gt;useReducer&lt;/code&gt;: store state and return state with a dispatch method. Is usually used for more complex methods. 
&lt;code&gt;useContext&lt;/code&gt;: a context object that allows the value to be passed around components that are children of the context


&lt;p&gt;Besides the hooks api, you can also define your own custom to share logic between components. More will be shared on a separate tutorial.&lt;/p&gt;

&lt;p&gt;These are what I think are good for dipping your toes into React ecosystem. There are many more topics that we have not covered, like folder structure, flux system and common practices and models in React. If you enjoy this tutorial, stay tuned to my future articles on more advanced React concepts.&lt;/p&gt;

</description>
      <category>react</category>
      <category>cheatsheet</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Enrolling into SUSS at 30 revives my love for programming</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sun, 30 Jan 2022 15:59:32 +0000</pubDate>
      <link>https://dev.to/wingpuah/enrolling-into-suss-at-30-revives-my-love-for-programming-1jc6</link>
      <guid>https://dev.to/wingpuah/enrolling-into-suss-at-30-revives-my-love-for-programming-1jc6</guid>
      <description>&lt;p&gt;I'm not a full believer of the utility of a university degree. I'm still not. I always wonder how many university graduates are underemployed. And I'm wondering about the percentage of the underemployed who utilises existing government programs to upskill in verticals unrelated to their studies. &lt;/p&gt;

&lt;p&gt;How many of your friends still work in a field related to their studies, be it poly or university?  &lt;/p&gt;

&lt;p&gt;Regardless, I'm now pursuing my part-time BSc &lt;strong&gt;Information and Communication Technology&lt;/strong&gt; (ICT) in SUSS. There are various motivations behind my decisions. One is the fact that we as a society are still very much paper-crazed. Yes, even though we are moving away from that. &lt;/p&gt;

&lt;p&gt;The curriculum at SUSS intrigues me because of the practicality of it. Web application development, object-oriented programming, application analysis and project management, to name a few. &lt;/p&gt;

&lt;p&gt;I am at a crossroad in my life. I am grateful for the stability of my current job. Still, there is a nagging feeling that there is something out there more dynamic and more fulfilling. Something that makes me eager to start my day, again. &lt;/p&gt;

&lt;p&gt;There are still many pathways that I could grow as a frontend developer, like OWASP, PWA, GraphQL, service workers, typescript.&lt;/p&gt;

&lt;p&gt;But I can't recall the last time that I sit in anticipation in front of my laptop. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I used to.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I used to love wrangling with the syntax of Javascript.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I used to spend hours on FreeCodeCamp, going through lessons after lessons.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I used to imagine the possibilities of the web.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used to.  That joy of opening up my IDE, and producing lines and lines of codes and marvel at my creation, it is missing. &lt;/p&gt;

&lt;p&gt;I don't know why and when it happens. Maybe it's burnout. Perhaps, it's the stark reality in comparison with what I imagine in my mind. I've been working in tech for a good 2-3 years. I still am amazed at how fast technology is advancing. I still love a good read on how technology and algorithms solve problems and improve people lives.&lt;/p&gt;

&lt;p&gt;It's human to crave progression. Some people set their goals to build a family. While others set their sights on financial goals. In preparation and in hope for something bigger than what I am today, I make a target to get a degree before I'm 35. &lt;/p&gt;

&lt;p&gt;I have usually enjoyed the acquirement of knowledge. Still, I'm pleasantly surprised how working on the assignments give me joy. Even though there is a deadline to meet, even though some fellow coursemates feel stressed out, I rejoice in my refound passion for playing around code. &lt;/p&gt;

&lt;p&gt;I am fortunate to find the pace of the modules manageable as I have some background knowledge. I love the vibrancy of the chat group when people in it discuss programming even when I don't always fully participate in it.  I guess I miss the feeling of being in a community, though programming is a lonely task to undertake. &lt;/p&gt;

&lt;p&gt;December will mark the end of my Year 1, Sem 1 and I look forward to more advance classes in future. &lt;/p&gt;

</description>
      <category>study</category>
      <category>suss</category>
    </item>
    <item>
      <title>Mathematics: My system and foundation learning journey [Day 1-3]</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sun, 30 Jan 2022 15:28:07 +0000</pubDate>
      <link>https://dev.to/wingpuah/mathematics-my-system-and-foundation-learning-journey-day-1-3-17p7</link>
      <guid>https://dev.to/wingpuah/mathematics-my-system-and-foundation-learning-journey-day-1-3-17p7</guid>
      <description>&lt;p&gt;This week, my year 2.2 has finally started. The 2 modules that started this week are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Basic Mathematical Optimsation (2 lessons)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mathematical foundations for data science (1 lesson) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prior to the start of the lessons, we are given access to our notes and assignments. Having only the knowledge of O-level Additional Mathematics, mathematics modules are the ones that I fear most for the whole of my university life, at least for the modules that I have taken so far. &lt;/p&gt;

&lt;p&gt;Looking through the notes, I'm not sure if they are full of cryptic wording or it's just me, I couldn't quite grasp the concepts simply by reading it. Still, the assignments seem pretty straight forward, the type of questions in which there are definitive ways of solving. It's straight forward on the premise that one has already grasp the methods of application. &lt;/p&gt;

&lt;p&gt;Honestly, I am looking forward to a module that will teach us the concepts of proofing and deriving solutions. Though I appreciate the applicability of how these courses are structured. &lt;/p&gt;

&lt;p&gt;Both the foundations and optimisation course starts off with linear algebra. The foundations course seem to also venture more into the programming side of thing. &lt;/p&gt;

&lt;p&gt;I'm glad that I've taken the foundations with the optimisation course as it does help me to fill up the gap that the optimisation course assumes knowledge on. &lt;/p&gt;

&lt;p&gt;We start off nice and easy, with the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vectors and matrix&lt;/li&gt;
&lt;li&gt;Various operations on vectors and matrix&lt;/li&gt;
&lt;li&gt;Programmatic way of dealing with vectors and matrix &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the overlapping topics covered by both of the courses. Almost at the end of the last 2 of the 3 lessons, I am attacked by the z monster. I wonder if it is my brain working hard to absorb the concept or if it is just a tired day for me. Anyway, side note for me to drink more caffeine when I have to attend these classes. &lt;/p&gt;

&lt;p&gt;While the foundations course take 1 lesson to cover the above, albeit in greater detail, the optimisation course squeezes in more concept for the past 2 lessons. &lt;/p&gt;

&lt;p&gt;In the first session, the additional topics are being covered: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gauss Elimination method&lt;/li&gt;
&lt;li&gt;LU decomposition &lt;/li&gt;
&lt;li&gt;Matrix iterative method &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are only taught how the methods work. While novel to me, I'm pretty sure these just take a few practices to get the gist of it. The good thing about SUSS is that all of our modules come with accompanying textbook, be it e-textbook or physical textbook. It could be interesting to delve into more details to understand the why/proofs of these methods. &lt;/p&gt;

&lt;p&gt;To be honest, it is not until the second lecture of optimisation course and the first lecture of foundations course that I see a good reason to learn these concepts. I have a vague idea that these concepts are applicable in machine learning and also in solving linear programming problems. Though, there is nothing too concrete in my mind yet. &lt;/p&gt;

&lt;p&gt;In the second session, we are given a glimpse of the application of linear algebra via linear programming. It touches briefly on&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear programming model&lt;/li&gt;
&lt;li&gt;Expressing the model in canonical and standard form &lt;/li&gt;
&lt;li&gt;Solving the model graphically &lt;/li&gt;
&lt;li&gt;Various terminology related to linear programming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main motivation of taking a data science minor and taking up mathematics elective is that I want to trade better. I want to be able to understand the derivatives analytics book that is full of mathematics and python. The python portion is easy to understand, but for the mathematics portion, I'm pretty much stuck to googling each symbol that I come across.  &lt;/p&gt;

&lt;p&gt;According to my notes, this optimisation process can be model a range of problems from airline scheduling, to least-cost manufacturing to distribution of goods. Perhaps, as a starter, I could formulate a risk-reward problem. Or most probably, I should read more into linear models and finish these modules first. &lt;/p&gt;

</description>
      <category>mathematics</category>
      <category>system</category>
      <category>optimisation</category>
      <category>career</category>
    </item>
    <item>
      <title>5 difficult things about being a self-taught developer</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sat, 28 Mar 2020 10:14:18 +0000</pubDate>
      <link>https://dev.to/wingpuah/5-difficult-things-about-being-a-self-taught-developer-oma</link>
      <guid>https://dev.to/wingpuah/5-difficult-things-about-being-a-self-taught-developer-oma</guid>
      <description>&lt;p&gt;Over the years, there has been a huge interest in learning programming. Tech jobs remain as one of the top-paying jobs in the world. And in Singapore, &lt;a href="https://www.marketing-interactive.com/skills-shortage-a-major-issue-for-sg-employers-in-e-commerce-era/"&gt;technological skills shortage&lt;/a&gt; remains a major issue for Singapore employers.&lt;/p&gt;

&lt;p&gt;If you have the relevant technical skills and portfolio, you could enter the technological industry. As a &lt;a href="https://www.thegeekwing.com/technology/musings/2018/08/05/the-girl-called-wing/"&gt;self-taught developer&lt;/a&gt; myself, I find that there are many channels to look for jobs. Demand for IT professional continues as Singapore is position at the frontier of the technological frontier. With the increase in demand for skilled IT professional, many companies are fighting for a limited amount of talents. In an interview conducted by Asian Correspondent, it is reported that nearly &lt;a href="https://asiancorrespondent.com/2018/10/job-seekers-technology-jobs-singapore/"&gt;9 in 10 Chief Information Officers find it difficult to find qualified IT professionals&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My formal academic background is in aviation management and services. However, throughout my decade of working life, my choices of career have mostly been a result of being self-taught. Personal training, group fitness coaching and web development. While having the time and autonomy to explore my directions in my early twenties, the self-taught journey could have been smoother. Here are 5 things that I wish someone has told me when I first started my self-taught journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Learn to manage time
&lt;/h2&gt;

&lt;p&gt;Chances are when you first decide to embark on the self-taught journey, you are probably doing it alongside your full-time job. If your end goal is to find a job as a developer, it can take anywhere &lt;a href="https://www.reddit.com/r/learnprogramming/comments/7fpycf/selftaught_programmers_how_long_did_it_take_you/"&gt;from months to years&lt;/a&gt;.While learning, it could be tempting to put the notion of learning programming on the back burner and spend time relaxing. When I freelance, sometimes I tend to spend my day watching Netflix during standard office hours.&lt;/p&gt;

&lt;p&gt;We are born to move away from pain and towards pleasure. Programming can be sometimes an agonizing endeavour. Sometimes what seems to be an easy problem turns out consuming half of the day. One of the productive tools that I enjoy using is the Pomodoro Technique. The technique uses a timer to break down the work into intervals. For example. you could set your working time to 25 minutes interspersed with 3-5 minutes break. After 4 rounds of 25 minutes, you could take a longer break. Understanding your energy level throughout the day and matching that to the work you allocate for yourself in that period of time help to boost efficiency as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Not knowing how to start
&lt;/h2&gt;

&lt;p&gt;"What language should I learn?" is not the question to start off asking. I know I use to ask this question when I first start out.&lt;/p&gt;

&lt;p&gt;The question is not what language but what do you hope to achieve. Essentially, certain concepts of programming cross over to various programming languages. If you are just trying out programming, ask yourself, what do you enjoy doing. Do you prefer to design? Do you like to build things that you can see? Do you like logic? Do you like working with data? Essentially, you will narrow down your preference to front-end development, back-end development or database development, for a start.&lt;/p&gt;

&lt;p&gt;From there, personally, I will choose to find out what are the easier languages to initially pick up. The idea here is to learn the fundamentals and basic concepts of programming. In the beginning, it is about enjoying the process of solving a problem. One website that I use is &lt;a href="http://www.freecodecamp.com"&gt;www.freecodecamp.com&lt;/a&gt;. Once you have more confidence in programming, you can proceed to learn other frameworks, computer science fundamentals, data structure and algorithms, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Lack of structured system
&lt;/h2&gt;

&lt;p&gt;This is similar to the point above. It is very easy to find basic programming courses online. But you don't know what you don't know. When I was working in the fitness industry, I thought I have gained a good basic understanding of the intricacies of the human body: the anatomy, physiology and biomechanics. It isn't until I enrol into a Sports Science bridging course to realise that the scope of Sports Science goes deeper into how the movement begins from chemical and electrical impulses.&lt;/p&gt;

&lt;p&gt;I enjoy the classes. And I love the social setting. But I prefer to learn as per my own pace online. In order to ensure there is enough coverage, you can look into the curriculum of a program and structure your own learning plan. It will help to validate this with an industry mentor to make sure that you are on the right track. In fact, nowadays, technology is moving so fast that people ended up needing to be self-taught in one way or another. But with the internet, there are many good online courses, which could even provide you support with an experienced mentor. One of them being &lt;a href="https://www.codecademy.com"&gt;Codecademy&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Lack of feedback loop
&lt;/h2&gt;

&lt;p&gt;Probably, the main fallback of being self-taught is that there are no immediate reliable sources of feedback loops. If you stand on the giant of the shoulders, you could achieve much more faster. Even as a front-end developer, sometimes I find it confusing to navigate through the various tutorials all trying to achieve the same thing. Honestly, why are there so many ways to write webpack with React.js? And we haven't even gone into server-side rendering, which, the last time I try, the code shatters into a blitsy allure.&lt;/p&gt;

&lt;p&gt;However, there is a web solution for this as well. Codementor is an on-demand marketplace to connect with expert mentors. If you prefer face-to-face, I find the developers in the developers meetup group are usually more than willing to help. And chances are the coding dojo and coding group usually have senior developers around to help you out.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Maintaining self discipline
&lt;/h2&gt;

&lt;p&gt;Perhaps the hardest of it all is having the motivation and willpower to show up on the desk day after day, consistently. There are going to be days that are going to be difficult. There will be days when you feel like this is all going no where. But you will only get to know the results if you work on it consistently for months and even years. But like what the late Steve Jobs says, "You can't connect the dots looking forward; you can only connect them looking backwards."&lt;/p&gt;

&lt;p&gt;There is no hard and fast rule when it comes to maintaining self-discipline. For me, I work best when I know there is a deadline. Or when there is a structure to follow. I also find out that I work well when I'm not at home.&lt;/p&gt;

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

&lt;p&gt;These are the 5 difficult things that I encounter during my self taught journey. Learning programming can be a lonely endeavour. At times, it can seem like there is no progress made. For the past 3 months, I take a break from learning front end development and reevaluate my path. One year back, my goal is firm, find a job as a front end web developer and move onto a full stack developer role.&lt;/p&gt;

&lt;p&gt;When I quit my previous full-time job, I start weighing in on my skillsets: communication and coordination definitely top the chart. While there are jobs that are approaching me for that role, I find myself missing the analytical work of employing design thinking and programming during these 3 months of programming hiatus. After going for a few rounds of interview, contemplating my goals in 5 years' time, researching for alternatives and asking for answers that I would probably never get, I'm back on track again.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>selfimprovement</category>
      <category>selftaught</category>
    </item>
    <item>
      <title>Handle data heavy application development on frontend</title>
      <dc:creator>Wing</dc:creator>
      <pubDate>Sun, 15 Mar 2020 09:11:35 +0000</pubDate>
      <link>https://dev.to/wingpuah/handle-data-heavy-application-development-on-frontend-32bi</link>
      <guid>https://dev.to/wingpuah/handle-data-heavy-application-development-on-frontend-32bi</guid>
      <description>&lt;p&gt;Are you frustrated by changing data structure? Or upset about deeply nested data that increases the complexity of frontend development? Don't. Don't be emotional over code.&lt;/p&gt;

&lt;p&gt;Jokes aside, modern day applications usually have to deal with data that is nested or relational in nature. For instance, when we use Redux, we could use &lt;a href="https://github.com/paularmstrong/normalizr"&gt;normalizr&lt;/a&gt; to store a normalized state structure.&lt;/p&gt;

&lt;p&gt;The increase complexity of data structure makes it tedious to develop. It will also cause bloat to the client devices. Frontend is meant to be light-weight and fast. Especially since we have to cater to mobile devices, we want to be careful in handling our data. The expensive rendering and computation should be delegated to the backend servers, which is a more controlled and scalable environment.&lt;/p&gt;

&lt;blockquote&gt;



&lt;strong&gt;Read&lt;/strong&gt;: &lt;a href="https://medium.com/hackernoon/frontend-in-the-backend-a-pattern-for-cleaner-code-b497c92d0b49"&gt;Backend-in-the-frontend: a pattern for cleaner code &lt;/a&gt;


-- &lt;em&gt;Hackernoon&lt;/em&gt;


&lt;/blockquote&gt;

&lt;p&gt;Even so, due to business requirements, we as frontend developers might have no choice but to parse complex data structure or data structure that is not optimised for the UI.&lt;/p&gt;

&lt;p&gt;We'll be using contrived example to get the point across. Let's take a look at the following JSON object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rd2PCpJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580570661/blog/2020/02/handleDataIntensive/sampleData.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rd2PCpJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580570661/blog/2020/02/handleDataIntensive/sampleData.svg" alt="nested data structure json" width="680" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The requirements
&lt;/h2&gt;

&lt;p&gt;Imagine if you have to create a data table for a list of dogs showing their favorite food and the supplier. Why that will be required, I don't know. Maybe, the software users are pet shop owners and they want to have an overview of the suppliers whom they could order the most items from and possibly negotiate a better deal.&lt;/p&gt;

&lt;p&gt;So back to the data. Let's say you are using a datatable plugin. The API of the datatable requires you to specify the dataKey for each column.&lt;/p&gt;

&lt;p&gt;Then comes the product owner, he has requested an additional requirement to show all the suppliers in one column.&lt;/p&gt;

&lt;h3&gt;
  
  
  So right now, you have a few things to solve:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You need to be able to access a nested dataKey, &lt;code&gt;favourites.food&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You will need to access all the &lt;code&gt;supplier.name&lt;/code&gt; in the array and concatenate them into a string for the data column.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your table is just simple presentational logic, and if the datatable allows dataKey definition with dot notation, i.e. &lt;code&gt;favourites.food&lt;/code&gt;, it will be fine to simply use the dataKey as it is. I believe in keeping things simple as it is, until proven otherwise.&lt;/p&gt;

&lt;p&gt;What if, throughout the app, there are multiple logic that needs to access this data? Are you going to get the dot notation in each cases, even if they might be deeply nested?&lt;/p&gt;

&lt;p&gt;Or because of fast changing business requirements, the data structure from the API changes frequently? What will you do to minimise the disruption of the data object?&lt;/p&gt;

&lt;p&gt;For me, I will transform the data object for use throughout my frontend code, so that the data integrity of the object in the frontend could remain even when the data structure from the API changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning from the giants
&lt;/h2&gt;

&lt;p&gt;I have been using &lt;a href="https://github.com/rjsf-team/react-jsonschema-form"&gt;react-jsonschema-form&lt;/a&gt; by Mozilla and &lt;a href="https://autodesk.github.io/react-base-table/api/basetable/"&gt;react BaseTable&lt;/a&gt; by Autodesk. I love how easy it is to define the data fields and data columns respectively. Using JSON object simplifies the parsing of the data and make it obvious to change the dataKey if the data structure changes. Both of the plugins also keep the data parsing logic loosely coupled to the UI rendering logic.&lt;/p&gt;

&lt;p&gt;If you have not used the plugins before, here is a sample code of how it is being used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React-jsonschema-form&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Ugj-IRX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580572913/blog/2020/02/handleDataIntensive/reactJsonSchemaForm.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Ugj-IRX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580572913/blog/2020/02/handleDataIntensive/reactJsonSchemaForm.svg" alt="react json schema form sample code" width="680" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React BaseTable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w2MhyvQc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580573364/blog/2020/02/handleDataIntensive/reactBaseTable.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w2MhyvQc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1580573364/blog/2020/02/handleDataIntensive/reactBaseTable.svg" alt="react basetable sample code" width="704" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My take is, you can roughly guess what each the plugin API do.&lt;/p&gt;

&lt;p&gt;The key &lt;code&gt;formData&lt;/code&gt; and &lt;code&gt;data&lt;/code&gt; is used to feed the data into the plugin. The &lt;code&gt;schema&lt;/code&gt; and &lt;code&gt;columns&lt;/code&gt; instruct the plugin on the dataKey to look for the data. The &lt;code&gt;uiSchema&lt;/code&gt; and &lt;code&gt;cellRenderer&lt;/code&gt; is where you could define any customisation to the UI rendering portion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to the drawing block
&lt;/h2&gt;

&lt;p&gt;With the above inspriations, I decide to contain all my data transformation through a json object. For lack of a better term, we will refer to this data object as schema.&lt;/p&gt;

&lt;p&gt;Using the requirements stated above, we determine that we need to build the following columns in the data table:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Id of the dog&lt;/li&gt;
&lt;li&gt;Name of dog&lt;/li&gt;
&lt;li&gt;Type of dog&lt;/li&gt;
&lt;li&gt;Cost of dog&lt;/li&gt;
&lt;li&gt;Supplier&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For us to be able to work with datatable easily, we want to transform our data to a single layer data object that we could pass into our datatable easily.&lt;/p&gt;

&lt;p&gt;This is my desired input for the datatable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D1Spbmx_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581146111/blog/2020/02/handleDataIntensive/dataForDataTable.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D1Spbmx_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581146111/blog/2020/02/handleDataIntensive/dataForDataTable.svg" alt="data for datatable data table" width="680" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what I want to define for my schema in order to achieve the input above. Note, in simple cases, it is easier to parse the data directly. However, if we want to conditionally render the schema and combine different schema, I find that having a data schema like below make it easy to read and extend my data structure.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./schema.js&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pmeTF3UP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581145796/blog/2020/02/handleDataIntensive/dataAdapterOutput.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pmeTF3UP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581145796/blog/2020/02/handleDataIntensive/dataAdapterOutput.svg" alt="data adapter output" width="696" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All I have to do to transform the backend data to my desired input is this.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./feData.js&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Olmv4TPw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581152405/blog/2020/02/handleDataIntensive/buildEntity.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Olmv4TPw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581152405/blog/2020/02/handleDataIntensive/buildEntity.svg" alt="build entity" width="680" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
More interested in the code? &lt;a href="https://github.com/wing-puah/dataAdapter"&gt;Find it here&lt;/a&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Breakdown
&lt;/h2&gt;

&lt;p&gt;There are a few premise that this data adapter is designed on.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We can extend the schema easily.&lt;/li&gt;
&lt;li&gt;We can define a default return value.&lt;/li&gt;
&lt;li&gt;If the schema cannot find a dataKey, it will return the full data.&lt;/li&gt;
&lt;li&gt;If the schema did not find a key, it will assume the usage of dataKey as key.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The concept of the dataKey and key is similar to the one used in base table. A &lt;code&gt;renderer&lt;/code&gt; will allow you to compute any relevant data. If you need to build a data that are in different levels, you just have to get to the highest level of the data structure and parse it accordingly.&lt;/p&gt;

&lt;p&gt;What makes react json-schema-form a powerful plugin is that the templates, widgets and plugins of the form are stored in an object and parse accordingly. With that principle in mind, I created a &lt;code&gt;buildSchema&lt;/code&gt; helper function that will return the whole schema with the data and user-defined value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sPQwnvql--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581177887/blog/2020/02/handleDataIntensive/buildSchema.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sPQwnvql--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581177887/blog/2020/02/handleDataIntensive/buildSchema.svg" alt="build schema javascript" width="680" height="93"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The schema output will map the schema with the existing data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wSDbCOWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581178507/blog/2020/02/handleDataIntensive/buildSchemaOutput.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wSDbCOWA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581178507/blog/2020/02/handleDataIntensive/buildSchemaOutput.svg" alt="build schema javascript" width="704" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While it might look trivial, by defining a &lt;code&gt;defaultSchema&lt;/code&gt; parameter, you can add any uiRenderer or extra key, value pair to be added to the schema. Returning a schema object will also help if you have custom UI rendering logic for different key. In your application, you will be able to define the UI rendering logic in the json schema. To use it in your UI component, you just have to map through the schema like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MDLNvIYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581179269/blog/2020/02/handleDataIntensive/schemaUiRenderer.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MDLNvIYe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/thegeekwing/image/upload/v1581179269/blog/2020/02/handleDataIntensive/schemaUiRenderer.svg" alt="build schema javascript" width="680" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;That's it. This is how I handle nested data and introduce a data adapter to a data intensive application. Having a schema thaat I could quickly refer to contributes to making my data easy to reason about. This reduces the cognitive load for me when I'm developing. The added benefit of easily adding a uiRenderer allows me to build flexible custom UI. Want to render it as row? Want to give it a different font size? With this structure, it is easy to pinpoint the exact dataKey to update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are some techniques that you use to reduce the complexity of your project? Share with me below.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>data</category>
      <category>adapter</category>
    </item>
  </channel>
</rss>
