<?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: adro.codes</title>
    <description>The latest articles on DEV Community by adro.codes (@hurricaneinteractive).</description>
    <link>https://dev.to/hurricaneinteractive</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%2F172480%2F393b8125-a9b4-48f2-8815-f0f3681e0bd0.jpeg</url>
      <title>DEV Community: adro.codes</title>
      <link>https://dev.to/hurricaneinteractive</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hurricaneinteractive"/>
    <language>en</language>
    <item>
      <title>Generate a Azure SAS token</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Thu, 24 Nov 2022 22:43:16 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/generate-a-azure-sas-token-lj3</link>
      <guid>https://dev.to/hurricaneinteractive/generate-a-azure-sas-token-lj3</guid>
      <description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/rest/api/eventhub/generate-sas-token"&gt;Azure Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you've created a Shared Access Policy (SAP) you will need to generate the token to use when send API calls.&lt;/p&gt;

&lt;p&gt;We can generate these ourselves, and luckily, Microsoft provides some code for us (see documentation above). Below is a small node script using this code to make life easy.&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;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// In seconds - week&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EXPIRES_IN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;7&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;createSharedAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saKey&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="nx"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;saName&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;saKey&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing required parameter&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;EXPIRES_IN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saKey&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SharedAccessSignature sr=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;encoded&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;sig=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;se=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp;skn=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;saName&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;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="c1"&gt;// Endpoint&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="c1"&gt;// SAP Name&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saKey&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="c1"&gt;// Primary or Secondary Key&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="nx"&gt;createSharedAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saKey&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;From what I can tell, there isn't a max for the &lt;code&gt;EXPIRES_IN&lt;/code&gt; variable. So if you want something that never expires, you can set it to 1000 years.&lt;/p&gt;

&lt;p&gt;You'll need to fill in those 3 variables based on your project and then run. &lt;code&gt;node &amp;lt;filename&amp;gt;.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That will spit out a value that you set the &lt;code&gt;Authorization&lt;/code&gt; header to whenever you send a message to your Queue/Topic/etc.&lt;/p&gt;




&lt;p&gt;If you don't want to use the node script or you want to read more about this, the documentation as always is your friend.&lt;/p&gt;

&lt;p&gt;✌️ Peace!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Module Driven Development - Scaling strategy for your next project</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Wed, 23 Nov 2022 21:46:03 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/module-driven-development-30mn</link>
      <guid>https://dev.to/hurricaneinteractive/module-driven-development-30mn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was originally posted on &lt;a href="https://papers.adro.codes/module-driven-development"&gt;papers.adro.codes&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;TLDR; Make the move towards developing feature-rich reusable modules instead of once-off components with undetermined dependencies. Module Driven Development aims to move the focus away from code briefly and focus on the cohesion of the codebase.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Cohesion
&lt;/h2&gt;

&lt;p&gt;Cohesion is the action or fact of forming a united whole. We measure cohesion as high/low and strong/weak in software development, aiming for high/strong cohesion is preferable, and is often a sign that your software is reusable, reliable and understandable. When focusing on this trait of software development we create fewer dependencies between the pieces of our software, allowing for modifications in one part that don't cause adverse effects on another.&lt;/p&gt;

&lt;p&gt;Knowing this, we as developers aim to implement practices and coding methodologies to improve cohesion, often if not always only focusing on our code and not the structure of our codebase. &lt;em&gt;Module Driven Development (MDD)&lt;/em&gt; aims to move the focus away from code briefly and focus on the cohesion of the codebase. Taking a step back and addressing the structure of our folders/files, implementing a consistent structure that is predictable can and will provide lasting benefits to any sized project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Weak Cohesion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Spoilt for choice without direction&lt;/strong&gt;. This is the world that many developers find themselves in, especially within the front-end community. One of the most popular UI libraries &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; is one of these choices and one that is made over 15 million times a week, according to the &lt;a href="http://npmjs.com/package/react"&gt;npm package&lt;/a&gt; page. Yet, if you were to look for guidance on a project structure you'll find a similar amount of articles discussing the topic. Why is that? React is un-opinionated meaning, it doesn't enforce any structure on you, it is up to the developers and teams to decide their approach. In my experience, this works great when working in small 1-2 person teams, but not 5-10 person teams across time zones. In team sizes like these, the reusability, reliability and collective understanding suffered.&lt;/p&gt;

&lt;p&gt;One piece of famous or infamous &lt;a href="https://react-file-structure.surge.sh/"&gt;advice&lt;/a&gt; was;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Move files around until it feels right&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In many ways, I agree with the underlying idea, don't overcomplicate too quickly and develop the structure as your application grows. I've followed this advice to some degree on many of my projects and everything worked out however, returning to those projects, later on, revealed a problem with this approach. It was vastly different to the project I am working on &lt;em&gt;now&lt;/em&gt;, moving through the project was sluggish and inefficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cohesion was weak.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Through this realisation, I started working on a new approach. One where I respect the advice of moving files around until it feels right, but with the confidence that returning to the project in the future will feel as familiar as the project I am working on in the present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strengthen Cohesion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Analysing the problem
&lt;/h3&gt;

&lt;p&gt;We've identified that the approach of "move files around until it feels right" can lead to weak cohesion. That is, it can lead to a codebase that isn't scalable or understandable. Below is a representation of a common project structure for many React (or Front-end in general) projects (left) and the location of various &lt;code&gt;user&lt;/code&gt; related components and functionality (right).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5_czyUej--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0yzw75epxsgmnkehxy1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5_czyUej--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0yzw75epxsgmnkehxy1.png" alt="Diagram of a common Front-end project structure. With an example focusing on one component." width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, this appears to be manageable. Different parts are separated into logically categorised folders. However, if you have worked in a codebase similar to this, you'll be aware of the challenges as the project scales. Every new component required adds at least 1 more file/folder to 2 or more of your root folders. Soon, you'll run out of names for files, each folder will contain 50+ files ranging from User related components to your Footer. Additionally, some knowledge sharing is required to define a &lt;code&gt;container&lt;/code&gt; component, or your &lt;code&gt;styles&lt;/code&gt; will slowly migrate to the respective component folder.&lt;/p&gt;

&lt;p&gt;All of these problems and more I have faced coming into large projects that use these techniques. The best I can do is hope that the changes I am required to do only span 1 or 2 files across as many folders, although there is usually still time required to find the start of the breadcrumb trail to follow.&lt;/p&gt;

&lt;p&gt;Analysing this structure, we can say that the structure is influenced by the file type. It is grouping &lt;code&gt;.css&lt;/code&gt;, &lt;code&gt;.d.ts&lt;/code&gt;, &lt;code&gt;.stories.tsx&lt;/code&gt;, &lt;code&gt;.gql&lt;/code&gt; etc files into separate folders to establish a separation of domains. We can also identify potential scaling concerns, as more pieces are added, these domain folders will continue to grow, increasing the time needed to ramp up development on an existing feature. Finally, identifying cross-component dependencies becomes harder as there isn't a single-entry point that can be easily identified for imports.&lt;/p&gt;

&lt;p&gt;With these points in mind, we will look at and compare the proposed structure used for Module Driven Development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proposing MDD
&lt;/h3&gt;

&lt;p&gt;Below is the representation of the &lt;code&gt;UserProfile&lt;/code&gt; when organising the files using Module Driven Development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wL4Y5ZDY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kira623hftrro0ohro99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wL4Y5ZDY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kira623hftrro0ohro99.png" alt="A diagram showing the transition to using Module Driven Development" width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are still separating different parts of the component into &lt;code&gt;ui&lt;/code&gt;, &lt;code&gt;styles&lt;/code&gt; etc folders, with one key difference. They are all contained within the &lt;code&gt;UserProfile&lt;/code&gt; module. In the next section, I will be outlining some of the principles of MDD, for now, I want to compare this structure to the problems we identified with the previous project structure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"...the structure is influenced by the file type", "grouping... files into separate folders to establish a separation of domains."&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;We are still separating by file type (within a module) however, the key difference here is we are establishing separation through product/project domains rather than the files. These domains are influenced by the problem domain your project is operating in and create a connection between the modules and your requirements.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"...as more pieces are added, these domain folders will continue to grow, increasing the time needed to ramp up development on an existing feature."&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;A project will always have a growing file structure. However, with MDD the growth is contained to the top-level &lt;code&gt;modules&lt;/code&gt; folder and any module groupings. Rather than spread across several folders.&lt;/li&gt;
&lt;li&gt;The more important benefit here is in regard to updating existing features. Since a feature would be contained within a module, it is much easier to locate the module and be presented with the full picture. It will also lower the cognitive load to scroll through or search for files across your entire solution.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;"identify cross-component dependencies"&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;This issue now becomes trivial. If you're using something like path aliases with Typescript, you'll be able to do a global search for &lt;code&gt;@module/UserProfile&lt;/code&gt; and find all imports referencing that module.&lt;/li&gt;
&lt;li&gt;Additionally, this provides the benefit of being in control of your module API. If your entry is at &lt;code&gt;@module/UserProfile&lt;/code&gt;, you can decide what is exported and what isn't. Allowing for both public and private components/functionality. Using this approach, you will be able to identify when a "private" piece of code is needed in another module. This could signal that some refactoring is needed to make a piece of code more globally accessible.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a fairly simple restructure of our project, we've been able to address each of the major problems identified with the previous approach. The codebase is now easier to navigate and understand. We've strengthened the overall cohesion.&lt;/p&gt;

&lt;p&gt;Let's continue and look at 4 principles that I recommend for MDD.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Think narrow and broaden your horizon&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuous refactoring&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Importance of consistent structure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modules can have modules&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Principles
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Think narrow and broaden your horizon
&lt;/h4&gt;

&lt;p&gt;It is often tempting to identify something as generic and implement it in a common &lt;code&gt;utilities&lt;/code&gt; or &lt;code&gt;lib&lt;/code&gt; folder. This principle goes against that way of working slightly, instead of prematurely extracting functionality, first place it within the module that is being worked on, this will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Encapsulate all the functionality within the module and,&lt;/li&gt;
&lt;li&gt;Allow modules to be easily transferred to new projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This does open the question of, what if a piece of functionality is needed in another module. That leads to the second principle of &lt;strong&gt;Continuous refactoring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: there is a very high chance that your project will still contain a &lt;code&gt;utilities&lt;/code&gt; or &lt;code&gt;hooks&lt;/code&gt; module. The difference here is in the contents of the folder. Instead of containing ALL utilities or hooks, the code in this folder would have been identified as functionality that is generic and needed in several places. Once again, making tracking dependencies easier.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Continuous refactoring
&lt;/h4&gt;

&lt;p&gt;When a piece of existing functionality is identified as something generic, minor refactoring can take place to move the functionality to a commonplace. I am a big advocate for "&lt;em&gt;leave it cleaner than when you found it&lt;/em&gt;". Having the chance to do a bit of refactoring allows you as a developer to revisit old code and clean it up while extracting the functionality. Not only does this keep your codebase healthy, but you may also stumble on existing bugs that haven't been reported yet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Importance of consistent structure
&lt;/h4&gt;

&lt;p&gt;The modules you write are only as good as their structure. This may take some work with your team to identify the structure that works for them however, the importance here is, to keep it consistent, not just within the current project but within future projects. This will give any team member a basic understanding of where to locate code if they are new to a project. It will also aid new team members, once they are onboarded into one codebase, they can comfortably navigate any other codebase. Below outlines a structure that I use on projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ui&lt;/code&gt; - a collection of UI (React, Vue, etc) components. You can also place stories here if you're using Storybook.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;service&lt;/code&gt; - a collection of hooks used throughout the components. This can range from utility hooks to hooks that perform API calls.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;context&lt;/code&gt; - define Context/State for the module (Read more about &lt;a href="https://www.adro.codes/vault/react-micro-contexts"&gt;Micro Contexts&lt;/a&gt; for details on module-based context).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;common&lt;/code&gt; - define common types, utilities and constants for the module.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;styles&lt;/code&gt; - any styling required for the components.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;integration/data-access&lt;/code&gt; - define GraphQL queries, and data transformation needed for the component.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spec&lt;/code&gt; - any tests that are required. It is up to you whether to place this in an enclosing folder. For example, &lt;code&gt;ui/spec&lt;/code&gt;, &lt;code&gt;common/spec&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Modules can have modules
&lt;/h4&gt;

&lt;p&gt;When it makes sense, or to create further domain separation, a module can have nested modules. Above we defined a &lt;code&gt;UserProfile&lt;/code&gt; module, this would make more sense to be a part of a &lt;code&gt;user&lt;/code&gt; or &lt;code&gt;authentication&lt;/code&gt; module, allowing you to group together Login, Sign up, User profile, User Settings, etc in one folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BXCzF0sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5alefz6rlwxe2378hjh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BXCzF0sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5alefz6rlwxe2378hjh6.png" alt="A diagram showing an authentication module with several sub-modules." width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The useful approach here is, that the top-level &lt;code&gt;authentication&lt;/code&gt; module can share the consistent folder structure as above allowing all nested modules to share common pieces of functionality with each other, for example, the &lt;code&gt;AuthenticationContext&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strong Cohesion
&lt;/h2&gt;

&lt;p&gt;We've identified what is causing weak cohesion in a codebase and addressed these concerns with the techniques and principles of Module Driven Development. The techniques allow us to structure projects in a predictable, scalable and understandable way, allowing the codebase to stay consistent across project boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cohesion is strong.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Case study
&lt;/h2&gt;

&lt;p&gt;The theory of a methodology and the utilisation of one are two different things. I would like to present a case study of a recent JAMStack project I was a part of. Although the client has to remain anonymous, I will describe the problem tackled and how implementing MDD allowed the codebase to be used by multiple businesses owned by the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  The client and requirements
&lt;/h3&gt;

&lt;p&gt;The client was a health and fitness brand with two separate businesses, a personal training business and an education business. They needed to continue being separate websites, but ideally share the same components and CMS to allow for a consistent user interface and experience, while allowing staff to have a consistent way to update both websites.&lt;/p&gt;

&lt;p&gt;From these requirements, we knew that reusability across the projects would be a necessity. With that, cross-component dependencies should be kept at a minimum to allow them to be shareable without needing to share unrelated code. Unfortunately, the codebases needed to remain separate in this case and we weren't able to utilise a package distributor like npm. We also had to keep the CMS instances separate, so transferring components between websites was a bit manual, which is why the cross-component dependencies would need to be kept to a minimum.&lt;/p&gt;

&lt;h3&gt;
  
  
  Applying Module Driven Development
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dN_svpfF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbp71jaca5eyyqgnffdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dN_svpfF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbp71jaca5eyyqgnffdh.png" alt="A diagram showing the relationship between page sections and their module" width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We started with identifying the different sections of the website and categorised them into several modules, some of these were top-level modules, while others could be grouped into a more generic module, for example, a &lt;code&gt;banner&lt;/code&gt; module which included 4 sub-modules.&lt;/p&gt;

&lt;p&gt;The authoring experience allowed the client to construct pages using "Lego Blocks", allowing them to stack sections of a page on top of each other. Each section had it's own &lt;em&gt;Model&lt;/em&gt; or &lt;em&gt;Content Type&lt;/em&gt; associated with them. Not only does this allow for the configuration of the component to be easily located, but the integration into the CMS could also be included in the module itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g2LCEDmB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnwgkytainioy3oz7w8c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g2LCEDmB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnwgkytainioy3oz7w8c.png" alt="A diagram showing the process from integration to rendering" width="880" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allowed us to create a system where modules could be included in the data querying process. Once the data has been fetched, we can loop through the received data, identify the module the data belongs to and render the component to the page.&lt;/p&gt;

&lt;p&gt;This central "opt-in" system allowed components to be registered for requesting data and rendering and since both the integration and UI were contained within a module, if a component was developed specifically for one of the businesses, we would be able to copy over the module, register the module and have it immediately available for the client to use in their pages.&lt;/p&gt;

&lt;p&gt;This approach allowed the first website to be completed and live within ~2 months, with development on the second taking less than half that. The majority of the effort was spent working with the client to re-develop the IA (Information Architecture) and identifying a handful of modules that were required for the new business, a few of them being ported over to the original project once development was completed.&lt;/p&gt;

&lt;p&gt;The most encouraging part for me was, I had little to no input on the second project, however, I was tasked with porting over those selected components. I received a ticket with the title "&lt;em&gt;Move over components X &amp;amp; Y to project one&lt;/em&gt;". The following were the steps I took:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloned project two.&lt;/li&gt;
&lt;li&gt;Located the module folders for X &amp;amp; Y.&lt;/li&gt;
&lt;li&gt;Copied them over to project one.&lt;/li&gt;
&lt;li&gt;Configured the CMS for project one.&lt;/li&gt;
&lt;li&gt;Registered the components.&lt;/li&gt;
&lt;li&gt;Pushed the changes.&lt;/li&gt;
&lt;li&gt;Moved the ticket to review.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process took less than an hour to complete. I would call that a win for using the Module Driven Development methodology. The consistent codebase across both projects allowed me to very efficiently navigate the second project, the developers on the second project followed the patterns outlined in project one and created two modules with zero outside dependencies (other than common UI components), making the porting process effortless.&lt;/p&gt;

&lt;p&gt;There was, however, one aspect of the project that was unfortunate, the need for separate codebases. Ideally, if you have a client with multiple businesses that should share components and functionality, keeping the code in one codebase would be preferable.&lt;/p&gt;

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

&lt;p&gt;We've been able to define a very important metric that we measure software against, cohesion, and apply that metric to a common practice in the Front-end development world. Through that lens, we were able to identify several key problems that impact these can have on the scalability and developer experience of the codebase. Through utilising the Module Driven Development methodology, we saw these problems lessen, strengthening the cohesion of our codebase, and finally, we looked at a case study where these techniques allowed for rapid development and share-ability between projects.&lt;/p&gt;

&lt;p&gt;I hope that you are able to take some of these concepts and apply some of them to your workflow as an engineer. One of the best parts of this methodology is, it does not require a full refactoring of a project. Because we focused on the folder structure employed, you are able to create a modules folder and place future features in their own &lt;code&gt;module&lt;/code&gt;, employing the continuous refactoring approach means as older features are worked on, they can slowly be migrated to a module of their own.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover Image Credit: &lt;a href="https://unsplash.com/photos/OSvN1fBcXYE"&gt;Mourizal Zativa&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>architecture</category>
      <category>jamstack</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using the Pub/Sub pattern in a Micro Frontend</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Sun, 12 Jun 2022 23:36:20 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/using-the-pubsub-pattern-in-a-micro-frontend-5edd</link>
      <guid>https://dev.to/hurricaneinteractive/using-the-pubsub-pattern-in-a-micro-frontend-5edd</guid>
      <description>&lt;p&gt;A few years ago the idea of a Micro Frontend solution became quite popular. I honestly haven't stayed up to date with the topic so not sure if it ever went anywhere. I did post &lt;a href="https://dev.to/hurricaneinteractive/microfrontends-what-and-why-4ji2"&gt;this article&lt;/a&gt; on dev.to to see what other peoples experience/opinion was on the topic. Looking back at the comments, the 1 user who gave a really detailed comment has either deleted their account or their comment... so thats fun.&lt;/p&gt;

&lt;p&gt;Anyway, a question I always had was about data sharing. Essentially, if you have a bunch of different isolated apps, possibly in different frameworks, how would you keep shared state synced across the site. For example, user details or authentication state. Maybe 1 app needs to trigger a modal in another (I had this problem recently).&lt;/p&gt;

&lt;p&gt;The way I solved it there was using the pub/sub design pattern. The modal was enclosed in a widget with a form to filter some data. It was within the navigation and was used to navigate the user to a area in the website, the navigation was managed by AEM and was disconnected from SPA that made up the rest of the page. In this SPA, there was a "Filter" button, once clicked it published an event, the widget subscribed on that event and once it received a message, would open the modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gor08kcO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esee0u1sxylptpvpptds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gor08kcO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/esee0u1sxylptpvpptds.png" alt="Image description" width="768" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This became a useful pattern in a few spots where really deeply nested components had to communicate to a much higher component. Rather than setting up some context with a bunch of &lt;code&gt;useEffects&lt;/code&gt; to listen to changes, I just published and subscribed to some events. Luckily this was only needed less than a handful of times so the solution didn't need to be the most robust, ultra fast, 0.002ms response time type solution.&lt;/p&gt;

&lt;p&gt;The way I implementated that was by dispatching a &lt;code&gt;CustomEvent&lt;/code&gt; with my data and adding event listeners on components for this event. It meant that I didn't need to keep a list of subscribers because &lt;code&gt;addEventListener&lt;/code&gt; did that for me, and I didn't need to loop through my subscribers to push them the changes, again, &lt;code&gt;addEventListener&lt;/code&gt; does that for me. Have a look at the mandatory "Counter" example &lt;a href="https://codesandbox.io/s/react-pub-sub-custom-event-bcwcn?file=/src/AppEvent.tsx"&gt;on Codesandbox&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;This worked out quite well, the project launched and I haven't thought about it much, until recently.&lt;/p&gt;

&lt;p&gt;I wanted to experiment with this design pattern a little to communicate between 2 apps in different frameworks. I decided to use &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; and &lt;a href="https://vuejs.org/"&gt;Vue&lt;/a&gt;, because I have experience with both.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to make a disclaimer right now. This is a very basic example, I built it without thinking too much. The chances that there is a Micro Frontend state solution is almost a 100%. If you were going to build something custom, I would probably use something like &lt;a href="https://rxjs.dev/guide/overview"&gt;RxJS&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;The first thing I did was build a function called &lt;code&gt;createSubscriptions&lt;/code&gt;, this would be used to keep track of subscribers, allow things to subscribe and call a action when the subscribers need to be notified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createSubscriptions&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;subscribers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&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;subscribe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&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;subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&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="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="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&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="na"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;:&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&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;sub&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&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="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;sub&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="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;ol&gt;
&lt;li&gt;
&lt;code&gt;subscribe&lt;/code&gt;: This method allows things to subscribe to and changes and accepts a callback function which will be the action that is called on &lt;code&gt;publish&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;publish&lt;/code&gt;: Any part of the application can send out a publish event. We go through each subscriber and call their action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To use this, you would create a topic with this method and then subscribe to it.&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;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSubscriptions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have that I created a Vue and React application that will listen to changes and allow the user to interact with the counter from each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React app&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;counter&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;setCount&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;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;counter&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;count&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="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="cm"&gt;/* UI */&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 need to set up our application state, this allows React to react to any state changes. Additionally we subscribe to the counter with the &lt;code&gt;setCount&lt;/code&gt; action, this works out because whenever the &lt;code&gt;publish&lt;/code&gt; is triggered it will call &lt;code&gt;setCount&lt;/code&gt; with the value. We also return the result of the &lt;code&gt;subscribe&lt;/code&gt; method which will unsubscribe the component when it unmounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vue app&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;mounted&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;unsub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;counter&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;unmounted&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;unsub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setCount&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="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;count&lt;/span&gt; &lt;span class="o"&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;decrement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;counter&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="k"&gt;this&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="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;I've omitted a few this but the concept is exactly the same as for the React app. I subscribe and pass it a method to update the state. I also have an action to &lt;code&gt;publish&lt;/code&gt; an updated count.&lt;/p&gt;

&lt;p&gt;To see all the code, check out &lt;a href="https://codesandbox.io/s/vue-react-pub-sub-5i7k5k?file=/index.html"&gt;this codesandbox&lt;/a&gt;. To play around with the result, check out &lt;a href="https://5i7k5k.csb.app/"&gt;the preview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I will say with the codesandbox link, the editor preview is really wacked when using the unpkg version of the libraries. The preview link is a lot nicer.&lt;/p&gt;




&lt;p&gt;Something I might eventually play around with is using this pattern but allow it to feel more "native" to the platform (again, I am sure this already exists).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JBxM07HL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7v8shvw7q9pc9iulrb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JBxM07HL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7v8shvw7q9pc9iulrb8.png" alt="Image description" width="813" height="929"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea being that there are methods to provide React with a hook to interact with the topic and create a store for Vue to interact with the topic. This would allow you to subscribe to a topic anywhere across the app with a standardised approach and keep the data in sync, which sounds pretty awesome.&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;useCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSubscriptionHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&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;counterStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSubscriptionStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;And that concludes my little adventure of using the Pub/Sub pattern to communicate between two different frontend applications. It was quick, it was dirty but I think it works decently well. Definitely something to keep in mind if I ever have another use case for this in a frontend application.&lt;/p&gt;

&lt;p&gt;Peace! ✌️&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue</category>
      <category>pubsub</category>
    </item>
    <item>
      <title>Response validation with Yup</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Mon, 06 Jun 2022 01:06:11 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/response-validation-with-yup-2018</link>
      <guid>https://dev.to/hurricaneinteractive/response-validation-with-yup-2018</guid>
      <description>&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Many times in our Frontend we just "accept" that an API response is what it should be. In Typescript we hide behind generics to type cast, but what if our API is a success with a data structure that we didn't expect? This happened a few times in a recent project. The backend logic for the API hit about 4 different services (that we had no control over), each of these are points of failure. Sometimes one would silently fail causing the API to be a &lt;code&gt;200&lt;/code&gt; with invalid data. I had a great time.&lt;/p&gt;

&lt;p&gt;Here is what I am talking about:&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;getMe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&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://get.profile&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="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Surely `json` will be the shape me need, nothing can go wrong&lt;/span&gt;
    &lt;span class="nx"&gt;renderMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Nothing will ever go wrong&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, 99% of the time, this is fine, and 99% of the time, I do this as well... &lt;em&gt;Probably shouldn't, but here we are.&lt;/em&gt; We kinda assume that if something goes wrong with the response then the &lt;code&gt;catch&lt;/code&gt; will catch it. Otherwise, we're all good. This doesn't just happen with custom &lt;code&gt;fetch&lt;/code&gt; calls. In React, if you use a fetch hook, many times it will allow you to pass in generics (&lt;code&gt;useFetch&amp;lt;Profile&amp;gt;()&lt;/code&gt;) to say what the shape of the data will be. Again, this works, I do it, but there isn't a lot of safety from incorrect data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idea:&lt;/strong&gt; I have been thinking about is using a validation library, in this case &lt;a href="https://github.com/jquense/yup"&gt;yup&lt;/a&gt; to add a extra layer of protection (this idea will work with any validation library). Usually, if we're working with forms we already have a validation library installed, so we aren't really introducing extra dependencies into our project. Additionally, if you're a Typescript user, these libraries can make type definitions a lot easier as well!&lt;/p&gt;

&lt;p&gt;Looking at our example above, we need to introduce 2 extra things. One is our schema and the other is validating our &lt;code&gt;json&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema
&lt;/h3&gt;

&lt;p&gt;Continuing with the get profile idea, we'll create a &lt;code&gt;profile&lt;/code&gt; schema. Depending on how you like to structure your projects. This could be in a &lt;code&gt;profile.schema.ts&lt;/code&gt; or &lt;code&gt;profile.model.ts&lt;/code&gt; file. Allowing you to separate things a little easier.&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;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&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;yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;birthday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * For Typescript users, you can import `InferType` from yup
 * and export the Profile type
 * export type Profile = InferType&amp;lt;typeof profile&amp;gt;
 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validate the data
&lt;/h3&gt;

&lt;p&gt;Now that we have our &lt;code&gt;profile&lt;/code&gt; definition, we can validate our &lt;code&gt;json&lt;/code&gt;, and handle any &lt;code&gt;ValidationError&lt;/code&gt; that yup might throw.&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;ValidationError&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;yup&lt;/span&gt;&lt;span class="dl"&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;getMe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&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://get.profile&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;stripUnknown&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="nx"&gt;renderMe&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The response data is invalid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Uncaught error occured&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice a few things are different here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have removed our generics. If the &lt;code&gt;validate&lt;/code&gt; call is successful, then we can be confident that &lt;code&gt;data&lt;/code&gt; is in our &lt;code&gt;Profile&lt;/code&gt; shape.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;catch&lt;/code&gt; block, we can now test for this &lt;code&gt;ValidationError&lt;/code&gt; and provide the user some extra details about the issue, instead of a generic 'Something went wrong' message.&lt;/li&gt;
&lt;li&gt;(Optional) I also passed in &lt;code&gt;stripUnknown: true&lt;/code&gt; to the &lt;code&gt;validate&lt;/code&gt; options. As the name suggests, it will remove any data that isn't in our &lt;code&gt;profile&lt;/code&gt; schema. This makes the data more consistent but also 'forces' someone to update the schema if additional data is added.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using a hook library
&lt;/h3&gt;

&lt;p&gt;In the case that you are using a fetch hook of some description. Some of them may have a &lt;code&gt;validation&lt;/code&gt; option where you can do the same thing. Alternatively, I've seen that many allow for a &lt;code&gt;transform&lt;/code&gt; step. Giving you a chance to change the data before returning it to the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&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;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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useFetch&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://get.profile&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="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&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;data&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;h3&gt;
  
  
  That's all folks
&lt;/h3&gt;

&lt;p&gt;Aaaand... that is it. Nothing else to really add. If you take anything away from this it would be, don't fully trust that your data is as expected. Adding additional checks in your components or logic won't hurt anyone. Validation libraries are usually very performant and already installed in many projects, utilising them to standardise schema definitions, type definitions and API data may provide some additional benefits to your projects. It could also help with mocking data, I am sure there are libraries out there that can take one of these schemas and output some JSON that matches the structure.&lt;/p&gt;

&lt;p&gt;Below is a &lt;a href="https://codesandbox.io/s/yup-response-validation-6jtohl?file=/src/index.ts"&gt;Codesandbox&lt;/a&gt; (hopefully it shows up) with this idea implemented, feel free to play around a bit. I did set the console to be open, but it sometimes vanishes so it might be best to open it in a different tab. Play around with the &lt;code&gt;me&lt;/code&gt; function and return some weird data to see if the validation works.&lt;/p&gt;

&lt;p&gt;Peace! ✌️&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Bit of a disclaimer:&lt;/em&gt; the ideas in this article are just ideas. I haven't been able to test them out fully yet. Complex data structures or conditional responses might require a more complex schema. I have noticed with complex schemas that the &lt;code&gt;InferType&lt;/code&gt; becomes a "everything is optional" type, which isn't always ideal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/yup-response-validation-6jtohl"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>JAMstack or Jamstack?</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Thu, 03 Jun 2021 23:15:56 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/jamstack-or-jamstack-4kpp</link>
      <guid>https://dev.to/hurricaneinteractive/jamstack-or-jamstack-4kpp</guid>
      <description>&lt;p&gt;Quick and silly question. I have seen it used both ways and in other ways. But lets do a "poll" to see what the results are.&lt;/p&gt;

&lt;p&gt;Comment your answer (or your preferred variation) or react with;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❤️: JAMstack&lt;/li&gt;
&lt;li&gt;🦄: Jamstack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Peace ✌️&lt;/p&gt;

</description>
    </item>
    <item>
      <title>PWA: FetchEvent.respondWith error on Safari</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Fri, 19 Feb 2021 10:00:20 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/pwa-fetchevent-respondwith-error-on-safari-148f</link>
      <guid>https://dev.to/hurricaneinteractive/pwa-fetchevent-respondwith-error-on-safari-148f</guid>
      <description>&lt;p&gt;Recently I have been working on a &lt;a href="https://web.dev/progressive-web-apps/"&gt;PWA&lt;/a&gt; for a client. I chose to use &lt;a href="https://www.gatsbyjs.com/"&gt;Gatsby&lt;/a&gt; to build out the front end and luckily it comes with some great plugins to help with building PWAs. Mainly the &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-plugin-offline/"&gt;offline&lt;/a&gt; and &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-plugin-manifest/"&gt;manifest&lt;/a&gt; plugins. After configuring those and building out the proof of concept, I deploy the site to Netlify and started testing on different devices.&lt;/p&gt;

&lt;p&gt;It all goes off without a hitch until I get to iPad Safari... Where after adding the app to the Home Screen and playing around with it, I turn off my wifi to test the offline mode. And I am met with this lovely error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: "FetchEvent.respondWith received an error: TypeError: There seems to be no connection to the Internet."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are correct error, there is no internet connection, that is the point.&lt;/p&gt;

&lt;p&gt;After spending a while Googling, as you do, I found two things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Apple doesn't like the term PWA, kinda irrelevant but worth noting.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;LOT&lt;/strong&gt; of other people were having the same issue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I tried several StackOverflow and Github solutions, with no luck. Eventually, I decided to go back to basics and create the most bare-bones PWA I could find. Which lead me to &lt;a href="https://medium.com/james-johnson/a-simple-progressive-web-app-tutorial-f9708e5f2605"&gt;this tutorial&lt;/a&gt; on Medium by &lt;a href="https://medium.com/@james.johnson280"&gt;James Johnson&lt;/a&gt;. It was the &lt;code&gt;Hello World&lt;/code&gt; of PWAs. Literally. Anyway, I followed the tutorial, deployed on Netlify and proceeded to test on iPad, with no issues! So something was wrong with the Gatsby build and not the iPad.&lt;/p&gt;

&lt;p&gt;I made two changes to my project, which were all pushed at the same time and ended up fixing my issue. In all honesty, I am not 100% sure which one was the actual fix and at this point, I am too scared to test.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. I added apple specific metadata
&lt;/h3&gt;

&lt;p&gt;These tags were mentioned in the tutorial I followed above. After looking at the built version of the site, I noticed these apple specific meta tags weren't being generated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're not using Gatsby, I'd recommend adding these meta tags in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of your pages, and seeing if it fixes your issue.&lt;/em&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Helmet&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-helmet&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;PageWrapper&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="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="nc"&gt;Helmet&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;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"apple-mobile-web-app-capable"&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"yes"&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;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"apple-mobile-web-app-status-bar-style"&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"black"&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;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"apple-mobile-web-app-title"&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App Title"&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;Helmet&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;I used the &lt;a href="https://www.npmjs.com/package/react-helmet"&gt;react-helmet&lt;/a&gt; package to add additional metadata to all my pages. The meta tag that seems the most important would be &lt;code&gt;apple-mobile-web-app-capable&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Updated the Workbox &lt;code&gt;globPatterns&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In my &lt;code&gt;gatsby-config.js&lt;/code&gt; file, I updated the manifest plugin options to include &lt;code&gt;cache_busting_mode: 'none'&lt;/code&gt;, which is required when you specify a new &lt;code&gt;globPattern&lt;/code&gt;. Then under the offline plugin I updated the workboxConfig to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;workboxConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;globPatterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/*.{js,jpg,png,html,css}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found this pattern while diving into the StackOverflow rabbit hole (I can't find the link again...).&lt;/p&gt;




&lt;p&gt;That is it, after making those changes and pushing the code. The PWA started working on iPad devices. I'd say to test the first change before trying the second one (if you're using Gatsby), it seems to be the more relevant change.&lt;/p&gt;

&lt;p&gt;Hopefully, this has helped you in some way. I spent a few hours looking at this issue so I was pretty happy when it started working. Plus, why not share my solution so other people don't have to spend hours pulling their hair out.&lt;/p&gt;

&lt;p&gt;Peace! ✌️&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Godot: Show custom editor warnings on Nodes</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Sun, 03 Jan 2021 05:13:46 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/godot-show-editor-warnings-on-nodes-2p8p</link>
      <guid>https://dev.to/hurricaneinteractive/godot-show-editor-warnings-on-nodes-2p8p</guid>
      <description>&lt;p&gt;Have you ever wanted to add the warning triangle on custom nodes that you can see on an &lt;code&gt;Area2D&lt;/code&gt; or &lt;code&gt;KinematicBody2D&lt;/code&gt; node? Well, then you're in luck because it is actually pretty easy!&lt;/p&gt;

&lt;p&gt;For this example, we're going to create a custom &lt;code&gt;Enemy&lt;/code&gt; node that requires a &lt;code&gt;Sprite&lt;/code&gt; child node. That will give you a good starting point to extend the functionality to fit your purpose.&lt;/p&gt;

&lt;p&gt;First, create a new script that inherits from the &lt;code&gt;Node2D&lt;/code&gt; (or whatever node you'd like your &lt;code&gt;Enemy&lt;/code&gt; to inherit from). I am going to call my file &lt;code&gt;Enemy.gd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We will define our class name to be &lt;code&gt;Enemy&lt;/code&gt; and add the &lt;a href="https://docs.godotengine.org/en/stable/tutorials/misc/running_code_in_the_editor.html"&gt;&lt;code&gt;tool&lt;/code&gt;&lt;/a&gt; keyword. This will allow us to run code in the editor and show the required errors. One note here, I recommend reading the documentation for the &lt;code&gt;tool&lt;/code&gt; keyword as there are some caveats that you will need to know about.&lt;/p&gt;

&lt;p&gt;The top of your script should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gdscript"&gt;&lt;code&gt;&lt;span class="k"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Node2D&lt;/span&gt;
&lt;span class="k"&gt;tool&lt;/span&gt;
&lt;span class="k"&gt;class_name&lt;/span&gt; &lt;span class="n"&gt;Enemy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll add the magical function, &lt;code&gt;_get_configuration_warning&lt;/code&gt;. Whenever this function returns a non-empty string, it will show the warning in the editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gdscript"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;_get_configuration_warning&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we add the logic, create your new &lt;code&gt;Enemy&lt;/code&gt; node in a &lt;code&gt;Scene&lt;/code&gt; so you can see the warnings appear in the editor. If you've changed the return statement, you should see something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W6261Iev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c0adfdv45bfl8ni431xo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W6261Iev--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c0adfdv45bfl8ni431xo.png" alt="Editor warning example in godot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll only be looking at direct children, so we'll use the &lt;code&gt;get_children&lt;/code&gt; method and do a simple boolean check if the check includes a &lt;code&gt;Sprite&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gdscript"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;_get_configuration_warning&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;has_sprite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_children&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;Sprite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;has_sprite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;true&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;has_sprite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Sprite is required"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a boolean variable called &lt;code&gt;has_sprite&lt;/code&gt; and set it to &lt;code&gt;false&lt;/code&gt; by default. Then we loop through all the children, check if the child &lt;code&gt;is&lt;/code&gt; a &lt;code&gt;Sprite&lt;/code&gt; and set the variable to &lt;code&gt;true&lt;/code&gt;. After the loop, we check if the &lt;code&gt;has_sprite&lt;/code&gt; variable is still &lt;code&gt;false&lt;/code&gt; and if it is, then we return a message saying that a &lt;code&gt;Sprite&lt;/code&gt; is required.&lt;/p&gt;

&lt;p&gt;If you save the script, the warning should pop up with your message and adding a &lt;code&gt;Sprite&lt;/code&gt; as a child node should remove the warning.&lt;/p&gt;

&lt;p&gt;The cool thing here is the &lt;code&gt;is&lt;/code&gt; keyword, which allows us to;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tests whether a variable extends a given class, or is of a given built-in type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using this, we can test for any other nodes or other custom nodes that we have created.&lt;/p&gt;

&lt;p&gt;Again, this is a very simple example but will be a good starting point from which to extend further to suit your needs.&lt;/p&gt;




&lt;p&gt;Thank you for reading my article, it really means a lot! ❤️ Please provide any feedback or comments, I'm always looking to improve and have meaningful discussions.&lt;/p&gt;

&lt;p&gt;👋 until next time!&lt;/p&gt;

</description>
      <category>godot</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Extract key values into an array</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Fri, 29 May 2020 10:07:01 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/extract-key-values-into-an-array-ial</link>
      <guid>https://dev.to/hurricaneinteractive/extract-key-values-into-an-array-ial</guid>
      <description>&lt;h2&gt;
  
  
  Use case
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;You have an array of objects and want to pull out all the values related to the &lt;code&gt;amount&lt;/code&gt; into an array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What will happen
&lt;/h2&gt;

&lt;p&gt;We will be creating a &lt;a href="https://dev.to/damcosset/higher-order-functions-in-javascript-4j8b"&gt;Higher-order function&lt;/a&gt; that can be used with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/a&gt; method. The method will then loop through the items in an array and pull out all the values for a specific key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data structure
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;small&gt;I am providing a Vanilla JS and Typescript example, the interface can be ignored if you are using vanilla JS&lt;/small&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;arr&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="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a-a-a-a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b-b-b-b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method - Vanilla JS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cur&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;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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;
  
  
  Usage
&lt;/h2&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;amounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; [5, 50]&lt;/span&gt;

&lt;span class="c1"&gt;// Because the method is a HOF, we can create separate methods to use later&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAmounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&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;getIds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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;amounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getAmounts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; [5, 50]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getIds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; ["a-a-a-a", "b-b-b-b"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method - Typescript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Type definition for a `.reduce` method&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ReducerHOF&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;C&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="kr"&gt;number&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;A&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Extracts the values for a specific key
 *
 * @export
 * @template T
 * @template K
 * @param {K} k
 * @returns {ReducerHOF&amp;lt;T[K][], T&amp;gt;}
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&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;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ReducerHOF&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;][],&lt;/span&gt; &lt;span class="nx"&gt;T&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="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&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;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/*
For our example;
T = Data
K = "id" | "amount"
Return type, if K == "id" -&amp;gt; string[]
Return type, if K == "amount" -&amp;gt; number[]
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use &lt;a href="https://www.typescriptlang.org/docs/handbook/generics.html"&gt;Generics&lt;/a&gt; to add type safety to the method. For example, with vanilla JS you'll be able to get the values for the key &lt;code&gt;comments&lt;/code&gt;. Which will return an array of &lt;code&gt;undefined&lt;/code&gt; values; not ideal. Of course, you can expand the method to check if a key exists; it will also provide you with autocomplete options within your IDE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getKeyValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="c1"&gt;// -&amp;gt; [5, 50]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;This method allows you to pull out the values of any key in an array of objects. Using Higher-order functions allows you to encapsulate functionality to make more maintainable and readable code.&lt;/p&gt;




&lt;p&gt;Thank you for reading my article, it really means a lot! ❤️ Please provide any feedback or comments, I'm always looking to improve and have meaningful discussions.&lt;/p&gt;

&lt;p&gt;👋 until next time!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>VS Code define a #region</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Wed, 13 May 2020 01:43:10 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/vs-code-define-a-region-1cd1</link>
      <guid>https://dev.to/hurricaneinteractive/vs-code-define-a-region-1cd1</guid>
      <description>&lt;p&gt;just show me&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt; is definitely one of my favourite code editors and I use it all the time. Recently I stumbled upon the &lt;code&gt;#region&lt;/code&gt; keyword. Using this you are able to wrap a section of code that will be collapsed together. This makes organising code a lot easier and allows you to focus on the functionality you're writing and ignore everything else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/editor/codebasics#_folding"&gt;Folding Guide&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Example time
&lt;/h3&gt;

&lt;p&gt;&lt;small&gt;I will be showing off how to do this in JavaScript, but it is available in quite a very languages. See the guide above.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;minus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&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;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&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;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without folding, the best you can do, in terms of folding, is the following;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;minus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not bad but if you add appropriate jsdoc blocks the functions still take up a decent footprint. With regions, you are able to do the following;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// #region Math functions&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;minus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&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;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&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;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// #endregion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you are able to collapse the code at the &lt;code&gt;// #region&lt;/code&gt; definition, collapsing the code down 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="c1"&gt;// #region Math functions ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/editor/codebasics#_folding"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stay safe out there ❤️&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>vscode</category>
      <category>javascript</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Coursera: Yes/No/Maybe/??/Aliens?</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Wed, 18 Dec 2019 04:45:24 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/coursera-yes-no-maybe-aliens-5fg8</link>
      <guid>https://dev.to/hurricaneinteractive/coursera-yes-no-maybe-aliens-5fg8</guid>
      <description>&lt;p&gt;I am always looking for websites or resources that I can use to learn different &lt;em&gt;things&lt;/em&gt;. I briefly looked into Coursera the other day and was wondering...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is Coursera worth the money and did you find the material worth it (if you used it)?&lt;br&gt;
&lt;small&gt;my discussion question, 2k19&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a bonus, can you list resources that you use regularly to upskill, in any aspect of your career?&lt;/p&gt;




&lt;p&gt;&lt;small&gt;&lt;em&gt;I don't have an explanation for "Aliens" in the title&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>How do you find mentors</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Mon, 16 Dec 2019 23:01:58 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/how-do-you-find-mentors-35ni</link>
      <guid>https://dev.to/hurricaneinteractive/how-do-you-find-mentors-35ni</guid>
      <description>&lt;p&gt;Recently I started learning &lt;a href="https://golang.org/"&gt;go&lt;/a&gt;, I wanted to learn a new backend language and after playing around a bit I started really enjoying it. However, being new to the language I am not sure if I am doing anything wrong or if there are better ways of doing things.&lt;/p&gt;

&lt;h3&gt;
  
  
  The question is...
&lt;/h3&gt;

&lt;p&gt;How do you go about finding mentors or people to look over your code to provide a second opinion? Unfortunately, none of the people I work with knows go so I can't turn to them.&lt;/p&gt;

&lt;p&gt;Are there any websites or places you go to find someone to help you learn concepts and provide feedback on your work?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This doesn't have to be go specific, any guidance on the subject will be great!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Falling in love with Gatsby all over again</title>
      <dc:creator>adro.codes</dc:creator>
      <pubDate>Mon, 16 Dec 2019 03:45:02 +0000</pubDate>
      <link>https://dev.to/hurricaneinteractive/falling-in-love-with-gatsby-all-over-again-17gf</link>
      <guid>https://dev.to/hurricaneinteractive/falling-in-love-with-gatsby-all-over-again-17gf</guid>
      <description>&lt;p&gt;Earlier this year I started using Nextjs more and more for developing small web apps. I initially wanted to use Gatsby, because I love it but wasn't able to because I needed authentication and dynamic routes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can't do that with Gatbsy...&lt;br&gt;
&lt;small&gt;me being an idiot, 2k19&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is when I read the "&lt;a href="https://www.gatsbyjs.org/docs/adding-app-and-website-functionality/"&gt;Adding App and Website Functionality&lt;/a&gt;" and "&lt;a href="https://www.gatsbyjs.org/docs/building-a-site-with-authentication/"&gt;Building a Site with Authentication&lt;/a&gt;" pages on the Gatsby documentation. And oh &lt;strong&gt;BOY&lt;/strong&gt; did it change my view of Gatsby!&lt;/p&gt;

&lt;p&gt;Something finally clicked; Gatsby is just react. 🤯 I know right, what a mind-blowing statement. Obviously I knew that Gatsby sites are built with React etc, but I was fixated on the Gatsby way of building sites. Installing a source plugin, creating a &lt;code&gt;createPages&lt;/code&gt; loop to render some pages and throw it up on Netlify. However, when I started thinking of it as Create React App with more bells and whistles, anything and everything was possible.&lt;/p&gt;

&lt;p&gt;The first thing I did was add Firebase authentication to a site. Now, I am not going to go through any specifics since there is a great tutorial by &lt;a href="https://auth0.com/blog/securing-gatsby-with-auth0/"&gt;Auth0&lt;/a&gt; which I used as a base. The basic idea is;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a "private" page. &lt;code&gt;/pages/app.js&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Tell Gatsby to render any pages with a slug of &lt;code&gt;/app/*&lt;/code&gt; to that page.&lt;/li&gt;
&lt;li&gt;Add Reach Router or React Router routes to the &lt;code&gt;app.js&lt;/code&gt; page.&lt;/li&gt;
&lt;li&gt;Create all your auth methods. Login/Signup, log out, getCurrentUser etc&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, I slightly changed my approach from the Auth0 article. I added AppContext using the &lt;a href="https://reactjs.org/docs/context.html"&gt;React Context API&lt;/a&gt;. Which kept track of the auth state. I also created a Protected &lt;a href="https://reactjs.org/docs/higher-order-components.html"&gt;Higher-Order Component&lt;/a&gt; to wrap my private routes in. On load, it would check the auth state and either allow the user on the page or redirect them back to the login page.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;PRETTY FREAKING COOL!&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Now you might be thinking.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why is this cool&lt;br&gt;
&lt;small&gt;You, maybe... 2k??&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Lets talk about it
&lt;/h3&gt;

&lt;p&gt;You can add preview functionality. This is solved with Gatsby Cloud, but we are developers, reinvent everything again. You'd create a &lt;code&gt;pages/preview.js&lt;/code&gt; page and once an author is logged in, you can display all the draft posts by requesting them from your data source. Then you can route to &lt;code&gt;/preview/:id&lt;/code&gt;, which can then display the content of the page using the same template as the public page. This will require a bit of morphing of data but it will be worth it, eventually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ecommerce&lt;/strong&gt;. Provide an account to your customers to see past purchases or to see exclusive deals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PAAS&lt;/strong&gt;. Build out your public site using the usual Gatsby formula and provide potential customers with a quick process between discovery and conversion. Then the app part of your site can use the &lt;code&gt;pages/app.js&lt;/code&gt; method described above.&lt;/p&gt;

&lt;p&gt;Just think about it this way. Whatever you have built in React before, you can build it with Gatsby. The only difference, you can provide a super-fast, SEO friendly, experience to your customers to convert them quickly. Then use whatever backend or microservice architecture you want.&lt;/p&gt;

&lt;p&gt;Hopefully my rambling helped you give Gatsby another chance if you thought that it was too restrictive and couldn't be used to build large scale applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  ✌️
&lt;/h1&gt;

</description>
      <category>react</category>
      <category>gatsby</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
