<?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: Patrick R</title>
    <description>The latest articles on DEV Community by Patrick R (@patrixr).</description>
    <link>https://dev.to/patrixr</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%2F177924%2F95026384-532a-4c77-823c-f0150bca4776.png</url>
      <title>DEV Community: Patrick R</title>
      <link>https://dev.to/patrixr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patrixr"/>
    <language>en</language>
    <item>
      <title>Automated JIRA release notes</title>
      <dc:creator>Patrick R</dc:creator>
      <pubDate>Sun, 16 Aug 2020 10:52:49 +0000</pubDate>
      <link>https://dev.to/patrixr/automated-jira-release-notes-4f20</link>
      <guid>https://dev.to/patrixr/automated-jira-release-notes-4f20</guid>
      <description>&lt;p&gt;This is my submission to the &lt;a href="https://dev.to/devteam/announcing-the-github-actions-hackathon-on-dev-3ljn"&gt;#ActionsHackathon&lt;/a&gt;. It is a github action designed to generate release notes based on commit messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;My tendency to get tunnel vision when working has often led me to lose track of events happening in my team. The number of projects and repos being large, keeping track of release cycles had me worried.&lt;/p&gt;

&lt;p&gt;I built the &lt;a href="https://github.com/marketplace/actions/jira-release-notes"&gt;&lt;code&gt;patrixr/jira-release-notes&lt;/code&gt;&lt;/a&gt; action with the intent of being notified by email whenever one of our (many) apps got released.&lt;/p&gt;

&lt;p&gt;It works as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;compares&lt;/strong&gt; two git refs and reads all the new commits (typically when a pull request is merged)&lt;/li&gt;
&lt;li&gt;It finds JIRA ticket references in the commit messages (e.g ABC-123)&lt;/li&gt;
&lt;li&gt;Using jira credentials, it will retrieve the ticket info&lt;/li&gt;
&lt;li&gt;It will generate release notes in Markdown based on those tickets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The available outputs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PDF&lt;/strong&gt; - The action will always generate a pdf file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt; - Optional - If provided with a Sendgrid key and recipients, will forward the notes via email&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;DIY Deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;

&lt;p&gt;For details, head over to the github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/patrixr"&gt;
        patrixr
      &lt;/a&gt; / &lt;a href="https://github.com/patrixr/jira-release-notes"&gt;
        jira-release-notes
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🔀 Github action to generate release notes based on JIRA tickets
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Jira Release Notes&lt;/h1&gt;
&lt;p&gt;This action generates release notes based on JIRA ticket numbers found in commits, and creates a PDF file. It can also email you the notes.&lt;/p&gt;
&lt;p&gt;Built as part of the &lt;a href="https://dev.to/devteam/announcing-the-github-actions-hackathon-on-dev-3ljn" rel="nofollow"&gt;#ActionsHackathon&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
How it works&lt;/h1&gt;
&lt;p&gt;You need to provide 2 refs to the action, &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;base&lt;/code&gt;. The action steps are as followed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fetch all the commits between the &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;base&lt;/code&gt; refs&lt;/li&gt;
&lt;li&gt;Find any reference to JIRA ticket numbers, based on the &lt;code&gt;jira-code&lt;/code&gt; you provide&lt;/li&gt;
&lt;li&gt;Will fetch the ticket titles using the &lt;code&gt;jira-host&lt;/code&gt;, &lt;code&gt;jira-username&lt;/code&gt; and &lt;code&gt;jira-password&lt;/code&gt; you provide&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;pdf&lt;/code&gt; is set to true
4.1. Will generate a pdf with the list of changed tickets, and output the file path under the &lt;code&gt;pdf&lt;/code&gt; variable
otherwise
4.2. Will generate markdown with the list of changed tickets, and output it under the &lt;code&gt;markdown&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;(OPTIONAL) If the &lt;code&gt;email-to&lt;/code&gt; and &lt;code&gt;sendgrid-api-key&lt;/code&gt; are provided, and email will be sent…&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/patrixr/jira-release-notes"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You can also find it on the &lt;a href="https://github.com/marketplace/actions/jira-release-notes"&gt;Marketplace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usage example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Forward release notes&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;closed&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;live&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release-notes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event.pull_request.merged == &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate and email notes&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/jira-release-notes@v1.0.1&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pdf_generator&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;head&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{github.event.pull_request.head.sha}}&lt;/span&gt;
        &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{github.event.pull_request.base.sha}}&lt;/span&gt;
        &lt;span class="na"&gt;jira-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ABC'&lt;/span&gt;
        &lt;span class="na"&gt;jira-host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jira.mycompany.org&lt;/span&gt;
        &lt;span class="na"&gt;jira-username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.jira_username}}&lt;/span&gt;
        &lt;span class="na"&gt;jira-password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.jira_password}}&lt;/span&gt;
        &lt;span class="na"&gt;email-to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;john@mycompany.org,jane@mycompany.org'&lt;/span&gt;
        &lt;span class="na"&gt;sendgrid-api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.sendgrid_api_key}}&lt;/span&gt;
        &lt;span class="na"&gt;app-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Awesome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Service'&lt;/span&gt;
        &lt;span class="na"&gt;unshallow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Process the pdf&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "The generated pdf was ${{ steps.pdf_generator.outputs.pdf }}"&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;We have been using this tool within the &lt;a href="https://www.goodcity.hk"&gt;Goodcity Project&lt;/a&gt;, a system designed to gather, managed and distribute donations. The project lives under the umbrella of the non-profit &lt;a href="https://crossroads.org.hk"&gt;Crossroads Foundation&lt;/a&gt;. Our work is available on &lt;a href="https://github.com/crossroads"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ideas for improvement
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multiple email service support&lt;/li&gt;
&lt;li&gt;Custom Markdown template for email/pdf structure&lt;/li&gt;
&lt;li&gt;Support for other project management platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to reach out for any issue or suggestions :)&lt;/p&gt;

&lt;p&gt;Happy coding everyone !&lt;/p&gt;

&lt;p&gt;Cheers !&lt;/p&gt;

</description>
      <category>actionshackathon</category>
      <category>github</category>
      <category>actions</category>
      <category>jira</category>
    </item>
    <item>
      <title>Design pattern: JS Functional Chains</title>
      <dc:creator>Patrick R</dc:creator>
      <pubDate>Tue, 15 Oct 2019 08:20:17 +0000</pubDate>
      <link>https://dev.to/patrixr/design-pattern-js-functional-chains-2ahj</link>
      <guid>https://dev.to/patrixr/design-pattern-js-functional-chains-2ahj</guid>
      <description>&lt;h1&gt;
  
  
  Functional Chains: Implementation
&lt;/h1&gt;

&lt;p&gt;Writing a serializable chainable functional API in Javascript.&lt;/p&gt;

&lt;p&gt;All of the work below can be found in this &lt;a href="https://github.com/patrixr/functional-chain"&gt;functional chain builder&lt;/a&gt;. A ready-made and reusable npm module allowing you to generate a small API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I've long thought chainable APIs were both elegant and descriptive.&lt;/p&gt;

&lt;p&gt;And started playing around with a &lt;strong&gt;functional&lt;/strong&gt; and &lt;strong&gt;stateless&lt;/strong&gt; implementation, as a fun experiment. &lt;/p&gt;

&lt;h3&gt;
  
  
  The chain
&lt;/h3&gt;

&lt;p&gt;Here's an example the API I'm thinking of :&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;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result should be a re-usable function that applies the different commands in order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serialization
&lt;/h3&gt;

&lt;p&gt;Instead of applying the operations immediately, this API is designed to return a function. The reason for that is to allow &lt;strong&gt;serialization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's an example of how that would look like :&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;analyse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// output =&amp;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;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="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;What are the &lt;strong&gt;benefits&lt;/strong&gt; of serialization :&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing
&lt;/h4&gt;

&lt;p&gt;Serialization can be beneficial in testing: we can assert the operations are correct. Possibly replacing &lt;strong&gt;end to end&lt;/strong&gt; tests with simpler &lt;strong&gt;unit&lt;/strong&gt; tests\&lt;/p&gt;

&lt;h4&gt;
  
  
  Networking
&lt;/h4&gt;

&lt;p&gt;A serialized operation, is one that can be sent &lt;strong&gt;over the wire&lt;/strong&gt;, expanding the use cases of the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploiting JavaScript
&lt;/h2&gt;

&lt;p&gt;Let's take a quick look at the language features that allow this to be possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functions are first-class objects
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A programming language is said to have First-class functions when functions in that language are treated like any other variable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;source: mozilla.org&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What does that mean for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we can pass functions around as &lt;strong&gt;arguments&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;we can &lt;strong&gt;set properties&lt;/strong&gt; to functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scoping and closures
&lt;/h3&gt;

&lt;p&gt;Closures are simpler to use than they are to explain. But here's what matters to us:&lt;/p&gt;

&lt;p&gt;If a &lt;strong&gt;function&lt;/strong&gt; creates another function, that new one can access its &lt;strong&gt;creator's scope&lt;/strong&gt;. It can in turn create a new function itself, and then again, and again... building a &lt;strong&gt;chain&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the chain
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Defining the API
&lt;/h3&gt;

&lt;p&gt;Before we actually write the chain, we need to define our api:&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;API&lt;/span&gt; &lt;span class="o"&gt;=&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;val&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;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&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;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nx"&gt;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&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;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nx"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&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;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty straightforward, each method returns a function that will apply the desired operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a wrapper function
&lt;/h3&gt;

&lt;p&gt;We've discussed the idea of returning functions out of functions. So let's create a base function that &lt;strong&gt;receives a chain&lt;/strong&gt;, and returns the &lt;strong&gt;completed operation&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;Wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;compute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Iterate through the chain and applies the calculations&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;chain&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;mem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&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;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;num&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;compute&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;At this point, we have &lt;strong&gt;no means of adding&lt;/strong&gt; anything to the chain. So let's &lt;strong&gt;add methods&lt;/strong&gt; to our &lt;code&gt;compute&lt;/code&gt; function, one for each that was defined previously.&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;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;API&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;API&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="nx"&gt;compute&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="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="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We already know we need to &lt;strong&gt;return a function&lt;/strong&gt;, that's the expected result of our chain. We also know, that this function should &lt;strong&gt;allow more functions to be chained&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most of you saw this coming, we can simply return our &lt;code&gt;Wrap&lt;/code&gt;, which does exactly that. The chaining takes place by providing it an &lt;strong&gt;extended chain&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;Wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;compute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Iterate through the chain and applies the calculations&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;chain&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;mem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&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;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&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;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;API&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;API&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="nx"&gt;compute&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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="nx"&gt;Wrap&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;compute&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;Currently, this usage would work :&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;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Wrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prettifying our API
&lt;/h2&gt;

&lt;p&gt;We now have a working chainable API. But the need to have &lt;code&gt;Wrap()&lt;/code&gt; prefixed to any chain is not of &lt;strong&gt;adequate elegance&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exporting user-friendly methods
&lt;/h3&gt;

&lt;p&gt;We want to be able to start our chain through one of the API's method. An easy way to achieve this is to have our module export those methods, with the wrap &lt;strong&gt;included&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="c1"&gt;// (API Object)&lt;/span&gt;

&lt;span class="c1"&gt;// (Wrap function)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;)&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;res&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="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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;API&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="nx"&gt;res&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;params&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;Wrap&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;params&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;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We essentially &lt;strong&gt;hide&lt;/strong&gt; the initial wrap inside the methods.&lt;/p&gt;

&lt;p&gt;Here's how our &lt;strong&gt;usage&lt;/strong&gt; currently looks :&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;multiplyBy&lt;/span&gt; &lt;span class="p"&gt;}&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="s1"&gt;./mychain&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;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already looking much better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding semantics
&lt;/h3&gt;

&lt;p&gt;Part of our initial design was to have an optional &lt;code&gt;and&lt;/code&gt; key word between each chain member. Although the need for that is arguable, let's do it for science.&lt;/p&gt;

&lt;p&gt;And the implementation couldn't be &lt;strong&gt;any simpler&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;Wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;compute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="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;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;API&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;API&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="nx"&gt;compute&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Semantics of choice&lt;/span&gt;
    &lt;span class="nx"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;andThen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;andThenDo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;compute&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;compute&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;Which brings us to our expected usage :&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;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multiplyBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;divideBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next Step: Serialization
&lt;/h2&gt;

&lt;p&gt;Thanks for reading through part one of my functional chain article.&lt;/p&gt;

&lt;p&gt;In order to keep them short, I will continue the topic of serialization in a separate article.&lt;/p&gt;

&lt;p&gt;If anyone has experience building chainable APIs, I would love to hear your approach and use cases.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Patrick&lt;/p&gt;

</description>
      <category>experiment</category>
      <category>javascript</category>
      <category>functional</category>
      <category>pattern</category>
    </item>
    <item>
      <title>React: Writing a custom API hook</title>
      <dc:creator>Patrick R</dc:creator>
      <pubDate>Tue, 20 Aug 2019 06:40:54 +0000</pubDate>
      <link>https://dev.to/patrixr/react-writing-a-custom-api-hook-l16</link>
      <guid>https://dev.to/patrixr/react-writing-a-custom-api-hook-l16</guid>
      <description>&lt;p&gt;Let's write a handy custom react hook to take care of the usual API logic we've all written time and time again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After a couple of years away from React, I'm re-educating myself on the best practices. This means : &lt;strong&gt;&lt;a href="//reactjs.org/docs/hooks-reference.html"&gt;Hooks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the very (&lt;strong&gt;very&lt;/strong&gt;) common flow we find across our apps is that of loading data from the API and displaying it. &lt;/p&gt;

&lt;p&gt;It usually looks somewhat like this :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--INPmDB-J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://files.tronica.io/manual-uploads/flowchart_api_fetch_5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--INPmDB-J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://files.tronica.io/manual-uploads/flowchart_api_fetch_5.png" alt="" width="457" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This has a tendency to result in very &lt;strong&gt;cluttered&lt;/strong&gt; components. Let's use our newfound knowledge of hooks to solve this.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the hook
&lt;/h2&gt;

&lt;p&gt;Based on the flow described above, it's pretty easy to define the data that we want our hook to provide. It will return :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The response data&lt;/li&gt;
&lt;li&gt;A loading flag&lt;/li&gt;
&lt;li&gt;An error (nulled on success)&lt;/li&gt;
&lt;li&gt;A retry method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given that I still appreciate delegating the request code to a service class, my thought is to have the hook call the service.&lt;/p&gt;

&lt;p&gt;Leading to the following usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&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;retry&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loadUserById&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparing the API service
&lt;/h2&gt;

&lt;p&gt;Let's use a little service class, in which we can place all of our beautiful ajax code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;APIService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;loadUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... ajax magic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;loadUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... ajax magic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;APIService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing the hook
&lt;/h2&gt;

&lt;p&gt;Our goal here is simply to combine standard react hooks to create all of our required fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  The state
&lt;/h3&gt;

&lt;p&gt;React already provides us with the &lt;a href="https://reactjs.org/docs/hooks-reference.html#usestate"&gt;useState&lt;/a&gt; hook to create and update state properties.&lt;/p&gt;

&lt;p&gt;Let's generate our fields :&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;useAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;params&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&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="kc"&gt;null&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&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="kc"&gt;false&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;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onError&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="kc"&gt;null&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;
  
  
  Calling the service
&lt;/h3&gt;

&lt;p&gt;The React hook that comes in play here is &lt;a href="https://reactjs.org/docs/hooks-reference.html#useeffect"&gt;useEffect&lt;/a&gt;, in which we can run our asynchronous code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ... async code&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;However, we've decided that the hook would return a &lt;code&gt;retry&lt;/code&gt; method. So let's move the asynchronous code to its own function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// ... async code&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now call the correct service method, based on the hook's arguments&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;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Clear previous errors&lt;/span&gt;
  &lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Start loading indicator&lt;/span&gt;
    &lt;span class="nx"&gt;setIsLoading&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="c1"&gt;// Fetch and set data&lt;/span&gt;
    &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;APIService&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;](...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Set the error message in case of failure&lt;/span&gt;
    &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Clear loading indicator&lt;/span&gt;
    &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;

&lt;p&gt;And voila ! Our hook is ready for consumption.&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;useAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ---- State&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&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="kc"&gt;null&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;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&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="kc"&gt;false&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;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ---- API&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setIsLoading&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;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;APIService&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;](...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&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;fetchData&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 in a component
&lt;/h2&gt;

&lt;p&gt;Let's write a little example of how that might be used in a component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;HomeScreen&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;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&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;retry&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loadUsers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// --- Display error&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorPopup&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;retryCb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ErrorPopup&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// --- Template&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoadingSpinner&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/LoadingSpinner&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserList&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/UserList&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/View&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;There are many ways to avoid re-writing common code across the application. &lt;/p&gt;

&lt;p&gt;In the past I've often delegated some of that to a &lt;code&gt;Store&lt;/code&gt;, or used &lt;code&gt;Mixins&lt;/code&gt; to create components with all that logic ready to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom hooks&lt;/strong&gt; give us a whole new flavour and open up new strategies for dealing with problems.&lt;/p&gt;

&lt;p&gt;Happy to witness the evolution of practices.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Patrick&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>reacthooks</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Publishing my vitals over the cloud</title>
      <dc:creator>Patrick R</dc:creator>
      <pubDate>Mon, 12 Aug 2019 11:44:40 +0000</pubDate>
      <link>https://dev.to/patrixr/publishing-my-vitals-over-the-cloud-132e</link>
      <guid>https://dev.to/patrixr/publishing-my-vitals-over-the-cloud-132e</guid>
      <description>&lt;p&gt;Having grown up with an over-protective and worrying father, my moving away never sat quite well with him.&lt;/p&gt;

&lt;p&gt;After years of answering regular text messages assessing my well-being, I've decided to try out a different approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Project
&lt;/h2&gt;

&lt;p&gt;The idea is to build a dashboard that my father can regularly check to ensure that I'm alive and well. Hopefully reducing his anxiety and paranoia over my inescapable impending doom.&lt;/p&gt;

&lt;p&gt;I decided to leverage my enthusiasm for Fitbit products with my understanding of the cloud to build this.&lt;/p&gt;

&lt;p&gt;I settled on a VueJS + ExpressJS tech stack for fast prototyping. Details can always be found on my &lt;a href="https://github.com/patrixr" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's a very basic diagram of the concept&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_diagram.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Fitbit API
&lt;/h2&gt;

&lt;p&gt;Having both a connected scale and wristband, the &lt;a href="https://dev.fitbit.com/build/reference/web-api/" rel="noopener noreferrer"&gt;Fitbit API&lt;/a&gt; gives me access to a multitude of data points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Heart rate&lt;/li&gt;
&lt;li&gt;Daily activity&lt;/li&gt;
&lt;li&gt;Steps&lt;/li&gt;
&lt;li&gt;Body (Weight/Fat/BMI)&lt;/li&gt;
&lt;li&gt;Sleep info&lt;/li&gt;
&lt;li&gt;and many more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to have our server periodically retrieve data through the api.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Registering an application
&lt;/h3&gt;

&lt;p&gt;First things first, let's head over to the Fitbit developer console and &lt;a href="https://dev.fitbit.com/apps/new" rel="noopener noreferrer"&gt;register an application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This will provide us with a &lt;code&gt;CLIENT_ID/CLIENT_SECRET&lt;/code&gt; key pair required for an &lt;strong&gt;OAuth2&lt;/strong&gt; authentication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt; : &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;detailed&lt;/strong&gt; heart rate data, also known as &lt;em&gt;"Heart Rate Intraday Time Series"&lt;/em&gt; , is currently only available through the &lt;strong&gt;Personal&lt;/strong&gt; app type, which we are using today.&lt;/p&gt;

&lt;p&gt;Given that this project only displays data, the app should be marked as &lt;strong&gt;Read-Only&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_fitbit_app_screenshot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_fitbit_app_screenshot.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Authenticate
&lt;/h3&gt;

&lt;p&gt;For a quick and painless authentication, I am using the &lt;a href="https://www.npmjs.com/package/passport-fitbit-oauth2" rel="noopener noreferrer"&gt;passport-fitbit-oauth2&lt;/a&gt; module.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating the Strategy
&lt;/h4&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;Strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FitbitStrategy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;clientID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;callbackURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CALLBACK_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;scope&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;sleep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;weight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heartrate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;location&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nutrition&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;social&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&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;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// store the tokens&lt;/span&gt;
    &lt;span class="nf"&gt;done&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;h4&gt;
  
  
  Hooking it up to ExpressJS
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Strategy&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;authenticate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fitbit&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;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;successRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;failureRedirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/callback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;once&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access tokens eventually &lt;strong&gt;expire&lt;/strong&gt;, that can be detected by the return of a &lt;code&gt;401&lt;/code&gt; from the API. A sign for us to proceed with the &lt;a href="https://dev.fitbit.com/build/reference/web-api/oauth2/#refreshing-tokens" rel="noopener noreferrer"&gt;Token Refresh&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Retrieving data
&lt;/h3&gt;

&lt;p&gt;Now that we have the Fitbit &lt;strong&gt;access token&lt;/strong&gt;, we can start making calls to their Web API.&lt;/p&gt;

&lt;p&gt;Here's an example of how to retrieve todays' Heart Rate Intraday Time Series:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET https://api.fitbit.com/1/user/-/activities/heart/date/today/1d/1min.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server then returns the following JSON :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"activities-heart-intraday"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dataset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00:01:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"00:02:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datasetInterval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"datasetType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"minute"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the dashboard
&lt;/h2&gt;

&lt;p&gt;With this being a passion project, I pulled in a few libraries I love to quickly get going.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://vuejs.org" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; as a framework, a choice of comfort&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/QingWei-Li/vue-trend" rel="noopener noreferrer"&gt;Vue Trend&lt;/a&gt; for slick looking graphs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fontawesome.com" rel="noopener noreferrer"&gt;Font Awesome&lt;/a&gt; for the icons, a classic&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://daneden.github.io/animate.css/" rel="noopener noreferrer"&gt;Animate.css&lt;/a&gt; exclusively for the heart pulsing animation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a bit of wiring around, the following was birthed :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_app_screenshot_montage_large.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_app_screenshot_montage_large.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Securing the app
&lt;/h2&gt;

&lt;p&gt;The web app exposes very personal data of mine, notably my fat percentage which can be seen sky rocketing around the Christmas holidays. &lt;/p&gt;

&lt;p&gt;For this reason, I hooked up my own tiny CMS (&lt;a href="https://github.com/patrixr/pocket-cms" rel="noopener noreferrer"&gt;Pocket&lt;/a&gt;), which provides me with users, access control and an admin panel out of the box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_pocket_admin_screenshot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ffiles.tronica.io%2Fmanual-uploads%2Fvitals_pocket_admin_screenshot.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improvement ideas
&lt;/h2&gt;

&lt;p&gt;Here are a few things I'm thinking of adding or have considered :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My nutrition (would require me to input everything I eat)&lt;/li&gt;
&lt;li&gt;A button that reminds me to drink water&lt;/li&gt;
&lt;li&gt;My location, that may be a bit too much&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Despite this project being extremely small and simplistic, I enjoyed the concept of making family members happier through technology.&lt;/p&gt;

&lt;p&gt;Would love to hear your thoughts and experiences in writing code for well being.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;/p&gt;

&lt;p&gt;Patrick&lt;/p&gt;

</description>
      <category>vue</category>
      <category>node</category>
      <category>javascript</category>
      <category>api</category>
    </item>
    <item>
      <title>An outlook on state management</title>
      <dc:creator>Patrick R</dc:creator>
      <pubDate>Tue, 18 Jun 2019 02:19:19 +0000</pubDate>
      <link>https://dev.to/patrixr/an-outlook-on-state-management-469c</link>
      <guid>https://dev.to/patrixr/an-outlook-on-state-management-469c</guid>
      <description>&lt;p&gt;This article takes a step back to reflect on today's state management practices in &lt;em&gt;front-end&lt;/em&gt; web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not a tutorial
&lt;/h2&gt;

&lt;p&gt;With today's resources, it would likely take you less than a minute to discover an abundance of great tech guides on how to write robust web applications.   &lt;/p&gt;

&lt;p&gt;If you've spent a bit of time doing that, you've surely landed on tutorials for &lt;em&gt;"state container"&lt;/em&gt; libraries and patterns, aka &lt;em&gt;"stores"&lt;/em&gt;. Most famously &lt;strong&gt;Redux&lt;/strong&gt; which is often used in React apps, or it's Vue counterpart &lt;strong&gt;Vuex&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Frankly, I could not write better tutorials if I tried. Instead, what I want to do here is spend a moment to think about &lt;strong&gt;WHY&lt;/strong&gt; we are doing all of that, to learn what it truly means to write a good app.&lt;/p&gt;

&lt;p&gt;Before we continue, I will give a quick shoutout to Hassan Djirdeh's great tutorial on &lt;a href="https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87"&gt;Managing State in Vue.js&lt;/a&gt;. If you are looking for a more technical and hands-on article, definitely check it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a stateful system ?
&lt;/h2&gt;

&lt;p&gt;If you've never asked yourself the question of whether your system was of a stateful nature, then the odds are that it was.&lt;/p&gt;

&lt;p&gt;Let's try to define it as best we can :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An application is categorized as stateful if it stores data that will in turn affect the behaviour and output of the system&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To give that definition some context, let's take a simple example :&lt;/p&gt;

&lt;p&gt;Example: &lt;em&gt;A user logs into your application. The code retrieves a piece of user related data and stores it. The next time you open the application, the app reads that stored data, understands that you are logged in and directly opens your profile page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the above example the &lt;strong&gt;state&lt;/strong&gt;, which consists of the user's data, affects the &lt;strong&gt;behaviour&lt;/strong&gt; of the app which here decides to show you a different page.&lt;/p&gt;

&lt;p&gt;Writing an app in that manner is &lt;em&gt;so incredibly common&lt;/em&gt; that we rarely take a moment to think about it.&lt;/p&gt;

&lt;p&gt;... &lt;em&gt;but we really should&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Side effects
&lt;/h2&gt;

&lt;p&gt;Here is a common definition of a software bug&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A software bug is an error, flaw, failure or fault in a computer program or system that causes it to produce an incorrect or unexpected result, or to behave in unintended ways&lt;/em&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source: &lt;a href="https://en.wikipedia.org/wiki/Software_bug"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's bring our attention to one word: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;... or to &lt;strong&gt;behave&lt;/strong&gt; in unintended ways&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also present in the definition of a stateful system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...will in turn affect the &lt;strong&gt;behaviour&lt;/strong&gt; and output of the system&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Though this would seem obvious to some, poorly managing our data is a &lt;strong&gt;direct cause&lt;/strong&gt; of bugs, leading to instability. One common term is &lt;a href="https://en.wikipedia.org/wiki/Side_effect_(computer_science)"&gt;side effects&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;All of this loops back to data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data is unpredictable&lt;/li&gt;
&lt;li&gt;Data can be faulty&lt;/li&gt;
&lt;li&gt;Data can be mutated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's tie this all together with some scenarios to illustrate those side-effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Case 1: Unexpected mutation
&lt;/h3&gt;

&lt;p&gt;Let's start with a sample of data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is my first post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1560044669311&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We decide to display the &lt;strong&gt;date&lt;/strong&gt; as a user friendly &lt;strong&gt;string&lt;/strong&gt; showing how long ago the message was posted e.g "&lt;em&gt;1 hour ago&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Our junior developer, not knowing any better, decides to format it nicely, &lt;strong&gt;mutating&lt;/strong&gt; the data in the process:&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fromNow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If reading this line gave you an uneasy feeling, congratulations, you understand the &lt;strong&gt;dangers&lt;/strong&gt; of data mutation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast forward&lt;/strong&gt; to moments later in the application's life, when another piece of code reads that post, &lt;strong&gt;expecting&lt;/strong&gt; a number value.&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;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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; '1 hour ago'&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="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Invalid Date&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This, as you can expect, returns an invalid date, eventually leading up to a &lt;strong&gt;bug&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Case 2: Multiple sources of data
&lt;/h3&gt;

&lt;p&gt;A JWT token is returned after a successful user login. It is added to the &lt;strong&gt;local storage&lt;/strong&gt; and attached to requests when connecting to the server.&lt;/p&gt;

&lt;p&gt;The app is structured with multiple &lt;strong&gt;service classes&lt;/strong&gt;, nicely representing the different functionalities of the API, e.g&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;UserService&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;class&lt;/span&gt; &lt;span class="nx"&gt;SearchService&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;It wouldn't be too far fetched to have all of them hold an &lt;strong&gt;authToken&lt;/strong&gt; property to use when calling the API. &lt;/p&gt;

&lt;p&gt;e.g&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;apiCall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/some/url&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;Authorization&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;authToken&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with every user based application, comes a  &lt;strong&gt;logout&lt;/strong&gt; feature:&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;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jwt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;SearchService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearToken&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;That &lt;em&gt;kinda&lt;/em&gt; works, not great but let's go with it for the sake of making our point.&lt;/p&gt;

&lt;p&gt;Now comes a feature request, we want our user to be able to interact with his playlists. Simple, we add a new service :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PlaylistService&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;strong&gt;!Problem!&lt;/strong&gt; we forgot to clear the token of that new service in the logout method.&lt;/p&gt;

&lt;p&gt;What would now happen if I logged out of the app, we can imagine a multitude of bugs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app could modify user data even after logout&lt;/li&gt;
&lt;li&gt;The app could act on behalf of the wrong user&lt;/li&gt;
&lt;li&gt;The app could believe a user is still logged in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some would think that there's nothing inherently wrong in the architecture we're portraying but we shouldn't need to remember to clear the PlaylistService token. In the robust system we're about to build, &lt;strong&gt;we won't need to&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How resources define practices
&lt;/h2&gt;

&lt;p&gt;We don't need to go far back in history to remember when a computer's memory was measured in megabytes, even kilobytes.&lt;/p&gt;

&lt;p&gt;When we work on systems with limited resources, there's  a good incentive in &lt;strong&gt;mutating&lt;/strong&gt; data and &lt;strong&gt;reusing&lt;/strong&gt; memory. The risks of side effects in exchange of a low memory footprint is a fair &lt;strong&gt;tradeoff&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Today resources are usually plentiful. We can allow ourselves to use more data for the sake of &lt;strong&gt;stability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What does that mean in every day life: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing &lt;a href="https://en.wikipedia.org/wiki/Pure_function"&gt;pure functions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Recreating alternate datasets instead of mutating them&lt;/li&gt;
&lt;li&gt;Using language features to secure data (e.g &lt;code&gt;const&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Carefully selecting libraries e.g

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://immutable-js.github.io/immutable-js/"&gt;Immutable.js&lt;/a&gt; as its name suggests, it is specifically made to provide non-mutable structures &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://momentjs.com"&gt;Moment.js&lt;/a&gt; although a very powerful tool, it is also known for having mutating methods, tread carefully&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Practices change over &lt;strong&gt;time&lt;/strong&gt; and across &lt;strong&gt;fields&lt;/strong&gt;. Web development is now seeing patterns borrowed from &lt;a href="https://en.wikipedia.org/wiki/Functional_programming"&gt;functional programming&lt;/a&gt; as the two worlds start to mesh together. A great example of that is &lt;a href="https://elm-lang.org"&gt;Elm&lt;/a&gt;, a functional language that compiles to JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is the grass greener on the other side ?
&lt;/h2&gt;

&lt;p&gt;We've gone over a lot of downsides of building stateful systems. One question arises: &lt;strong&gt;Could we build stateless web apps&lt;/strong&gt; ?&lt;br&gt;
Although stateless designs have existed on the backend side for a while, it is not a question we often ask ourselves for front-end apps.&lt;/p&gt;

&lt;p&gt;Nothing prevents us technically from doing so, but applications are often &lt;strong&gt;designed as stateful&lt;/strong&gt;. An example of that would be a shopping cart: a feature revolving around the ability to &lt;strong&gt;store&lt;/strong&gt; and &lt;strong&gt;edit&lt;/strong&gt; data.&lt;/p&gt;

&lt;p&gt;Building an app with a state, although prone to side-effects, offers a lot of &lt;strong&gt;convenience&lt;/strong&gt; often taken for granted. The absence of local data would double efforts only to get around that restriction.&lt;/p&gt;

&lt;p&gt;So we know that the state is not going away, and we know that it is prone to errors. So how can we &lt;strong&gt;manage&lt;/strong&gt; it efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The birth of flux
&lt;/h2&gt;

&lt;p&gt;The most popular store containers are derived from the Flux pattern. Despite the differences we may find, they all try to solve the &lt;strong&gt;same problem&lt;/strong&gt; and share &lt;strong&gt;core values&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Formalization
&lt;/h3&gt;

&lt;p&gt;By their sheer existence, those containers bring the state to the front line of the application, and under the eyes of developers.&lt;/p&gt;

&lt;p&gt;No longer on the sidelines, it transforms the data into something &lt;strong&gt;official&lt;/strong&gt;, &lt;strong&gt;noticeable&lt;/strong&gt; and therefore &lt;strong&gt;worth taking care of&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Direct access
&lt;/h3&gt;

&lt;p&gt;Apps are typically built as a tree structure of components. The data &lt;strong&gt;cascades&lt;/strong&gt; down the tree, being passed on and on.&lt;/p&gt;

&lt;p&gt;That opens up a great number of opportunities for mishandling data. We could jokingly call that a software version of the &lt;a href="https://en.wikipedia.org/wiki/Chinese_whispers"&gt;Chinese whispers&lt;/a&gt; game.&lt;/p&gt;

&lt;p&gt;Flux-inspired stores can mitigate the risks, as components can retrieve the data straight from a source of truth.  &lt;/p&gt;

&lt;p&gt;The Chinese whispers analogy displays how &lt;strong&gt;information distortion&lt;/strong&gt; is greater the longer the chain is. This also leads us to a fair assumption that state containers are more valuable in &lt;strong&gt;larger apps&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Single source of truth
&lt;/h3&gt;

&lt;p&gt;Having a piece of information stored in multiple parts of the app has its own share of risks. It creates opportunities for it to get &lt;strong&gt;out of sync&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A managed store solves that by providing a single location in which to store information. It can be described as a &lt;strong&gt;golden source&lt;/strong&gt; of data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulation
&lt;/h3&gt;

&lt;p&gt;State containers will typically avoid exposing the state directly. For the simple purpose of &lt;strong&gt;protecting&lt;/strong&gt; it from unexpected mutations.&lt;/p&gt;

&lt;p&gt;For updates which are required, the store will expose a set of methods which will apply precisely the required changes to the data.&lt;/p&gt;

&lt;p&gt;By exposing &lt;strong&gt;limited and controlled mutations&lt;/strong&gt;, it reduces the number of potential unexpected and uncontrolled changes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Accountability and traceability
&lt;/h3&gt;

&lt;p&gt;When dealing with &lt;strong&gt;bugs&lt;/strong&gt; caused by an unexpected or wrong mutation, finding the source of that mutation can quickly become a hassle. Every piece of code is a potential suspect.&lt;/p&gt;

&lt;p&gt;Luckily, a state manager only allows changes through a &lt;strong&gt;limited&lt;/strong&gt; set of entry points. This &lt;strong&gt;narrows down&lt;/strong&gt; the list of suspects: either the mutator method itself, or whichever code called it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;Many thanks to those who have suffered through the entirety of the article.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick disclaimer: everything written here is the product of my understanding, experience and opinions, and should by no means be considered an absolute source of truth.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In addition, I would love to hear your thoughts and comments on this topic.&lt;br&gt;&lt;br&gt;
If anyone wishes to contribute and suggest changes, the paper will be available on my &lt;a href="https://github.com/patrixr"&gt;github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>vue</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
