<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jolene Langlinais</title>
    <description>The latest articles on Forem by Jolene Langlinais (@jolanglinais).</description>
    <link>https://forem.com/jolanglinais</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%2F208770%2F3baedebf-ab98-49a1-ab88-36f18ad0d1b7.jpg</url>
      <title>Forem: Jolene Langlinais</title>
      <link>https://forem.com/jolanglinais</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jolanglinais"/>
    <language>en</language>
    <item>
      <title>Vibe Coding Best Practices</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Wed, 10 Sep 2025 03:02:38 +0000</pubDate>
      <link>https://forem.com/jolanglinais/vibe-coding-best-practices-4go7</link>
      <guid>https://forem.com/jolanglinais/vibe-coding-best-practices-4go7</guid>
      <description>&lt;p&gt;AI coding tools are powerful accelerators, but only if used with intention. Seeing real gains requires structured workflows and making AI part of your &lt;em&gt;discipline&lt;/em&gt;, not a shortcut.&lt;/p&gt;

&lt;p&gt;Here’s how to get the most out of tools like Cursor and Claude on a serious engineering team:&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Plan&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Draft plans and iterate with AI to improve it&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask clarifying questions about edge cases&lt;/li&gt;
&lt;li&gt;Have it critique its own plan for gaps&lt;/li&gt;
&lt;li&gt;Regenerate an improved version&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Save the final plan in a temporary file and reference it in every prompt&lt;/p&gt;

&lt;p&gt;✅ Prompting with a well defined plan eliminates the vast majority of "&lt;em&gt;AI got confused halfway through&lt;/em&gt;" cases&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;TDD&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Implement code in &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development" rel="noopener noreferrer"&gt;TDD&lt;/a&gt; with AI&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prompt AI to write a failing test that captures the desired goal&lt;/li&gt;
&lt;li&gt;Review the test and ensure it captures the correct behavior&lt;/li&gt;
&lt;li&gt;Prompt AI to write code to make the test pass&lt;/li&gt;
&lt;li&gt;Iterate through running the test and fixing failures&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Prompting with human-reviewed tests results in implemented code passing the correct requirements&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Reasoning&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Keep this in prompts: &lt;code&gt;Explain your approach step-by-step before writing any code&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You need to walk before you can run, and putting adequate time into planning will make the implementation smoother&lt;/p&gt;

&lt;p&gt;✅ Prompting for reasoning results in fewer mistakes and the model revealing assumptions&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Context Curation&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Large projects and dumping context break AI attention. Be intentional on what you include to the context.&lt;/p&gt;

&lt;p&gt;Look into these solutions for context curation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/upstash/context7" rel="noopener noreferrer"&gt;Context7&lt;/a&gt; keeps your docs up to date without needing to re-paste snippets&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gitingest.com/" rel="noopener noreferrer"&gt;GitIngest&lt;/a&gt; curates codebases into summaries digestible for models&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Git Safety&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Rely on the fundamentals of git to have a fallback point prior to implementing something with AI. Commit granularly and prevent uncommitted changes piling up.&lt;/p&gt;

&lt;p&gt;✅ Prompting with a clean git state results in an easier isolation and rollback of AI-introduced bugs&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Prompt Focusing&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;❌ A poorly formed prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Here's my entire codebase. Why doesn't authentication work?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inputting &lt;em&gt;specific&lt;/em&gt; problems generate &lt;strong&gt;specific solutions&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Inputting &lt;em&gt;vague&lt;/em&gt; problems generate &lt;strong&gt;hallucinations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use specific code terminology in prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reference the exact identifiers from codebase, not generic business terms&lt;/li&gt;
&lt;li&gt;i.e., call &lt;code&gt;createOrder()&lt;/code&gt; and &lt;code&gt;processRefund()&lt;/code&gt; instead of 'place order' or 'issue refund'&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This precision helps the AI apply the correct abstractions and avoids mismatches between your domain language and code.&lt;/p&gt;

&lt;p&gt;✅ A well formed prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;*@src/auth.ts:85-90&lt;/code&gt; panics on &lt;code&gt;None&lt;/code&gt; when JWT is malformed*&lt;br&gt;
&lt;em&gt;Fix this and add proper error handling&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;File References&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;References files with &lt;code&gt;@src/database.ts&lt;/code&gt; instead of pasting code blocks&lt;/p&gt;

&lt;p&gt;✅ Prompting direct file references results in an up-to-date context, fewer used tokens, and a more readable prompt history&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Specifications&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Prompt &lt;em&gt;exactly&lt;/em&gt; what to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;For the new &lt;span class="sb"&gt;`validate_email`&lt;/span&gt; function, write tests for:
&lt;span class="p"&gt;-&lt;/span&gt; Valid email formats (basic cases)
&lt;span class="p"&gt;-&lt;/span&gt; Invalid formats (no @, multiple @, empty string)
&lt;span class="p"&gt;-&lt;/span&gt; Edge cases (very long domains, unicode characters)
&lt;span class="p"&gt;-&lt;/span&gt; Return value format (should be &lt;span class="sb"&gt;`Result&amp;lt;(), ValidationError&amp;gt;`&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Prompting specific test cases results in good test boilerplate generation&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Debugging&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;When stuck, prompt for a systematic breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Generate a diagnostic report:
&lt;span class="p"&gt;1.&lt;/span&gt; List all files modified in our last session
&lt;span class="p"&gt;2.&lt;/span&gt; Explain the role of each file in the current feature
&lt;span class="p"&gt;3.&lt;/span&gt; Identify why the current error is occurring
&lt;span class="p"&gt;4.&lt;/span&gt; Propose 3 different debugging approaches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Prompting specific instructions results in systemic thinking, instead of guess-and-check&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Style Guidelines&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Prompt a styling system in order to receive a consistent code quality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Code style rules:
&lt;span class="p"&gt;-&lt;/span&gt; Use explicit error handling, no unwraps in production code
&lt;span class="p"&gt;-&lt;/span&gt; Include docstrings for public functions
&lt;span class="p"&gt;-&lt;/span&gt; Prefer composition over inheritance
&lt;span class="p"&gt;-&lt;/span&gt; Keep functions under 50 lines
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`pretty_assertions`&lt;/span&gt; in test
&lt;span class="p"&gt;-&lt;/span&gt; Be explicit about lifetimes in Rust
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`anyhow::Result`&lt;/span&gt; for error handling in services and repositories.
&lt;span class="p"&gt;-&lt;/span&gt; Create domain errors using &lt;span class="sb"&gt;`thiserror`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Never implement &lt;span class="sb"&gt;`From`&lt;/span&gt; for converting domain errors, manually convert them
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Prompting consistent rules results in consistent code quality&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Code Review&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Treat every AI change like a junior developer's PR/MR, and thus check for risks such as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vulnerabilities (&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html" rel="noopener noreferrer"&gt;XSS&lt;/a&gt;, &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Injection_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;SQL injection&lt;/a&gt;, &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html" rel="noopener noreferrer"&gt;insecure direct object references&lt;/a&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html" rel="noopener noreferrer"&gt;Input validation&lt;/a&gt; robustness&lt;/li&gt;
&lt;li&gt;Information leakage, such as &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html" rel="noopener noreferrer"&gt;error messages&lt;/a&gt; or &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html" rel="noopener noreferrer"&gt;logging&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://planetscale.com/blog/what-is-n-1-query-problem-and-how-to-solve-it" rel="noopener noreferrer"&gt;N+1 query patterns&lt;/a&gt; and expensive loops&lt;/li&gt;
&lt;li&gt;Algorithm complexity and efficiency&lt;/li&gt;
&lt;li&gt;Unnecessary allocations and other performance bottlenecks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Correctness Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does it handle edge cases correctly?&lt;/li&gt;
&lt;li&gt;Verify error handling and null-handling&lt;/li&gt;
&lt;li&gt;Are there off-by-one errors or logical flaws?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Maintainability, Scalability, and Readability Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the code adhere to team standards and established design patterns?&lt;/li&gt;
&lt;li&gt;Is the code overly complex? Are names clear?&lt;/li&gt;
&lt;li&gt;Should this code even be added?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Prompting with an expectation of AI being smart but not wise results in considering if the feature or change is truly necessary and well-designed&lt;/p&gt;

&lt;h1&gt;
  
  
  Antipatterns
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The "Magic Prompt" Fallacy&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;❌ Prompting will not be perfect and AI will make mistakes&lt;/p&gt;

&lt;p&gt;✅ Prompting with good workflows result in good implementations&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Expecting Mind-Reading&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;❌ Prompting without state requirements do not result in correct inferences&lt;/p&gt;

&lt;p&gt;✅ Prompting with specifics results in good implementation&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Trusting AI with Architecture Decisions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;❌ Prompting a high-level system design results in poor implementation&lt;/p&gt;

&lt;p&gt;✅ Prompting with architecture already designed results in good implementation&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Ignoring Domain-Specific Context&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;❌ Prompting without context results in hallucinations&lt;/p&gt;

&lt;p&gt;✅ Prompting with direct reference to business logic, deployment constraints, and/or team conventions results in good implementation&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Pair Programming&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;For most implementation tasks, treat AI as a pair programming driver&lt;/p&gt;

&lt;p&gt;✅ AI has no ego or judgement, rather it has infinite patience and good memory&lt;/p&gt;

&lt;p&gt;❌ AI doesn’t always catch logic errors and rarely pushes back on bad ideas&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;AI coding tools can significantly boost productivity, but only if you use them systematically. The engineers seeing massive gains aren't using magic prompts, they're using disciplined workflows.&lt;/p&gt;

&lt;p&gt;Plan first, test everything, review like your production system depends on it (because it does), and remember two things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI is your intern, not your architect&lt;/li&gt;
&lt;li&gt;AI is a tool that is only as good as they way in which you use it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ℹ️ The material here is from both my own experience and referencing a blog I found on the subject:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forgecode.dev/blog/ai-agent-best-practices/" rel="noopener noreferrer"&gt;https://forgecode.dev/blog/ai-agent-best-practices/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>ChatGPT Prompt Framework</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Tue, 09 Jan 2024 15:09:39 +0000</pubDate>
      <link>https://forem.com/jolanglinais/chatgpt-prompt-framework-20h3</link>
      <guid>https://forem.com/jolanglinais/chatgpt-prompt-framework-20h3</guid>
      <description>&lt;p&gt;This prompt engineering framework for ChatGPT acts as a guide for providing a structured set of instructions to the AI model in order to receive fuller, more accurate, and more desirable results.&lt;/p&gt;

&lt;p&gt;I call this &lt;strong&gt;SPICIER&lt;/strong&gt; because it is the best anagram I could think of, but it doesn't perfectly match the order of categories.&lt;/p&gt;

&lt;h1&gt;
  
  
  S.P.I.C.I.E.R.
&lt;/h1&gt;

&lt;p&gt;ℹ️ &lt;em&gt;This, especially &lt;strong&gt;Input&lt;/strong&gt;, can and should be written for a computer, not a human.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;R&lt;/u&gt;ole&lt;/strong&gt;: Give ChatGPT a persona to give a response through the lens of&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;I&lt;/u&gt;nstruction&lt;/strong&gt;: What you want to get out of ChatGPT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;C&lt;/u&gt;ontext&lt;/strong&gt;: Help ChatGPT understand the context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;I&lt;/u&gt;nput&lt;/strong&gt;: The input data you want ChatGPT to respond to&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;S&lt;/u&gt;ource&lt;/strong&gt;: Reference websites to help shape the input to results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;E&lt;/u&gt;xclusions&lt;/strong&gt;: Further define parameters by omitting undesired results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;u&gt;P&lt;/u&gt;arameters&lt;/strong&gt;: Specify specific options or constraints, &lt;em&gt;i.e. the tone of voice, formatting, length&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;ROLE:&lt;/p&gt;

&lt;p&gt;Act as a software engineer expert in the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Koa&lt;/li&gt;
&lt;li&gt;Prisma&lt;/li&gt;
&lt;li&gt;Zod&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;INSTRUCTIONS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I will give you my code for a specific Koa middleware and the related Prisma schema&lt;/li&gt;
&lt;li&gt;You will change the code to do the following:

&lt;ul&gt;
&lt;li&gt;Check if &lt;code&gt;something123&lt;/code&gt; exists.&lt;/li&gt;
&lt;li&gt;If it does, send a patch to X API and ignore both Prisma and the Airtable response&lt;/li&gt;
&lt;li&gt;If it does not, send a post to Y API and create the record in Prisma&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CONTEXT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;submit&lt;/code&gt; Koa middleware to handles form submissions&lt;/li&gt;
&lt;li&gt;The following are arbitrary unique identifier variables:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;something123&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;something456&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CODE:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT CODE
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;EXCLUSIONS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assume my web application code is working and is setup correctly&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Node Service Template</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Fri, 28 Jul 2023 15:29:22 +0000</pubDate>
      <link>https://forem.com/jolanglinais/node-service-template-olm</link>
      <guid>https://forem.com/jolanglinais/node-service-template-olm</guid>
      <description>&lt;h2&gt;
  
  
  PNK Stack Service
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;P&lt;/strong&gt;ostgreSQL, &lt;strong&gt;N&lt;/strong&gt;ode, and &lt;strong&gt;K&lt;/strong&gt;oa&lt;/p&gt;

&lt;p&gt;This acts as a guide for creating a relatively production ready backend micro-service, which can be customized to your needs.&lt;/p&gt;

&lt;p&gt;The reference template repository can be found at &lt;a href="https://github.com/irmerk/pnk-stack" rel="noopener noreferrer"&gt;&lt;code&gt;irmerk/pnk-stack&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; with &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://koajs.com/" rel="noopener noreferrer"&gt;Koa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.prisma.io/" rel="noopener noreferrer"&gt;Prisma.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;All of this page assumes that you are using a Mac and that your software is up to date. If not up to date you may run into install issues when you install the packages below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell
&lt;/h3&gt;

&lt;p&gt;macOS now ships with &lt;a href="https://zsh.sourceforge.io/" rel="noopener noreferrer"&gt;Zsh&lt;/a&gt; as the default shell. If you want more customization and handy shortcuts, you can install &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;oh my zsh&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal Emulator
&lt;/h3&gt;

&lt;p&gt;You can use the Terminal app that ships with macOS, but &lt;a href="https://iterm2.com/" rel="noopener noreferrer"&gt;iTerm2&lt;/a&gt; is a popular and recommended alternative with more features and following. For information regarding prompt customization, see &lt;a href="https://dev.to/irmerk/bash-cli-readability-5882"&gt;Zsh Prompt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A helpful setting can also allow you to &lt;a href="https://apple.stackexchange.com/questions/136928/using-alt-cmd-right-left-arrow-in-iterm" rel="noopener noreferrer"&gt;use Alt/Cmd + Right/Left Arrow in iTerm&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text Editor / IDE
&lt;/h3&gt;

&lt;p&gt;Use whatever text editor / integrated development environment (IDE) you prefer. At the time of this writing, &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; is an extremely popular one with a built-in plugin manager for easily extending and customizing functionality.&lt;/p&gt;

&lt;p&gt;For helpful VSCode keyboard shortcuts to incorporate into your workflow, see their &lt;a href="https://code.visualstudio.com/docs/getstarted/tips-and-tricks" rel="noopener noreferrer"&gt;Tips and Tricks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My suggestions for &lt;a href="https://github.com/irmerk/outreach/blob/main/reference/vscode.md#extensions" rel="noopener noreferrer"&gt;VSCode extensions&lt;/a&gt; and &lt;a href="https://github.com/irmerk/outreach/blob/main/reference/vscode.md#keyboard-shortcuts" rel="noopener noreferrer"&gt;keyboard shortcuts&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Line Tools
&lt;/h3&gt;

&lt;p&gt;Install the &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; package manager for easy and relatively safe installation and upgrades.&lt;/p&gt;

&lt;p&gt;Recommended tools:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;&lt;code&gt;nvm&lt;/code&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Manages installations of Node.js and npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;nvm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.nvm &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export NVM_DIR="$HOME/.nvm"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zprofile &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] &amp;amp;&amp;amp; \. "/opt/homebrew/opt/nvm/nvm.sh" # This loads nvm'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zprofile &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; ~/.zprofile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; could be installed directly via &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; as well, but doing so makes it challenging to switch between versions. Some projects each require specific versions of &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; versions to work properly, so nvm installations are strongly preferred.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set your name and email address explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"&amp;lt;YOUR_NAME&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &amp;lt;YOUR_EMAIL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;a href="https://www.docker.com/get-started/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Rationale
&lt;/h2&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Makefile&lt;/code&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://spin.atomicobject.com/2021/03/22/makefiles-vs-package-json-scripts/" rel="noopener noreferrer"&gt;Used for clarity and speed&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://koajs.com/" rel="noopener noreferrer"&gt;Koa&lt;/a&gt;
&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I chose Koa because it is newer, less opinionated, lighter weight, and easier to customize than the standard of Express. Koa is modular and customizable because it requires modules for routing, the templating engine, and JSONP. This way, I can create middleware ourselves or use the built-in middleware.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Koa focuses more on modern features of the JavaScript ES6 language, like &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator" rel="noopener noreferrer"&gt;generators&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" rel="noopener noreferrer"&gt;async functions&lt;/a&gt;, and the &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; runtime. Moreover, it uses promise-based flows and async-await syntax to get rid of callbacks, making the code more manageable, cleaner, and more readable. Because it uses generator syntax instead of callbacks, I can use the &lt;code&gt;yield&lt;/code&gt; keyword to exit and then reenter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Koa uses a &lt;code&gt;context&lt;/code&gt; object, which encapsulates &lt;code&gt;req/res&lt;/code&gt; objects into one, helping us develop more efficiently by using several helpful methods. Finally, Koa uses cascading middleware. Thanks to asynchronous functions, middleware will run in a cascading fashion until the last middleware is reached.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;Axios&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HTTP Client Library for &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sindresorhus/got#comparison" rel="noopener noreferrer"&gt;Comparison to other libraries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I chose axios instead of &lt;a href="https://github.com/sindresorhus/got#install" rel="noopener noreferrer"&gt;got&lt;/a&gt; because “[the got] package is native &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" rel="noopener noreferrer"&gt;ESM&lt;/a&gt; and no longer provides a CommonJS export. If your project uses CommonJS, you will have to &lt;a href="https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c" rel="noopener noreferrer"&gt;convert to ESM&lt;/a&gt; or use the &lt;a href="https://v8.dev/features/dynamic-import" rel="noopener noreferrer"&gt;dynamic&lt;/a&gt; &lt;code&gt;import()&lt;/code&gt; function. Please don't open issues for questions regarding CommonJS / ESM.”&lt;/li&gt;
&lt;li&gt;GOT has issues with linting, TypeScript, ESM/CJS, and JSON.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Logging
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/winstonjs/winston/blob/master/docs/transports.md" rel="noopener noreferrer"&gt;logging transport&lt;/a&gt; is configured for logging to the console. This happening in a service set up in a cloud service can be configured to be picked up from &lt;code&gt;STDOUT&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Linting
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://unix.stackexchange.com/a/18789" rel="noopener noreferrer"&gt;Why I add a new line to the end of a file.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npx&lt;/code&gt;: When I run a command with &lt;code&gt;npx&lt;/code&gt;, it will check whether the command exists in the local &lt;code&gt;node_modules/.bin&lt;/code&gt; directory or in the system-wide installed packages. If it doesn't find the command, it will attempt to temporary install the package and execute it. This makes &lt;code&gt;npx&lt;/code&gt; an ideal tool to run the locally installed service being called.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.docker.com/engine/reference/builder/" rel="noopener noreferrer"&gt;Dockerfile&lt;/a&gt; &amp;amp; &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Dockerfile&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Dockerizing a service allows for it to behave the same regardless of the platform on which it is run. A &lt;a href="https://docs.docker.com/engine/reference/builder/" rel="noopener noreferrer"&gt;Dockerfile&lt;/a&gt; is a blueprint on which the Docker image is built. When the built image is running, it is called a container. Essentially, the container starts as a Dockerfile that has the instructions on how to build the Docker image. The same image can be used to spin up one or even hundreds of containers, which is why Docker is so useful for software scalability.&lt;/li&gt;
&lt;li&gt;I am using a slim production stage and a more feature-rich, development-focused dev stage.&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;NODE_ENV&lt;/code&gt; to &lt;code&gt;production&lt;/code&gt; &lt;a href="https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production" rel="noopener noreferrer"&gt;can increase performance by 3x&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Notice some of our commands are put together with an &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, creating &lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers" rel="noopener noreferrer"&gt;fewer Docker layers&lt;/a&gt;, which is good for build caching.&lt;/li&gt;
&lt;li&gt;Debian-based images because &lt;a href="https://martinheinz.dev/blog/92" rel="noopener noreferrer"&gt;it may be better in some cases than the more standard alpine linux image&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;docker-compose.yml&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Docker Compose is a way to more easily setup multiple services running with Docker in an ecosystem. The &lt;em&gt;big&lt;/em&gt; advantage of using Compose is you can define your application stack in a file, keep it at the root of your project repo (it’s now version controlled).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;.dockerignore&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Just like I wouldn’t use Git without .&lt;code&gt;gitignore&lt;/code&gt;, I use a &lt;code&gt;.dockerignore&lt;/code&gt; file to ignore files that I don’t want to land in our Docker image. It helps to keep the Docker image small and keep the build cache more efficient by ignoring irrelevant file changes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;dumb-init&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;I use &lt;code&gt;dumb-init&lt;/code&gt; because it will be the first process (&lt;code&gt;PID 1&lt;/code&gt;) and will handle the signal forwarding and the reaping of the zombie processes. It is a simple process supervisor and init system that helps to handle these situations.&lt;/li&gt;
&lt;li&gt;Docker containers usually run a single application, and for that application, it is normal to expect it to receive signals from the Linux environment. However, when running in the background (as a daemon), the application may not correctly handle the Linux signals, which can lead to zombie processes and not graceful termination.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Multiple Stages

&lt;ul&gt;
&lt;li&gt;Optimizing layers with multiple stages (build and production) in the &lt;code&gt;Dockerfile&lt;/code&gt; results in a drastically smaller image size:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;REPOSITORY      TAG     IMAGE ID        CREATED             SIZE
single-stage    latest  8ceb85286547    4 seconds ago       402MB
multi-stage     &amp;lt;none&amp;gt;  ec0680eefe42    About a minute ago  300MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/emmanuelnk/RESTful-Typescript-Koa" rel="noopener noreferrer"&gt;emmanuelnk/RESTful-Typescript-Koa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/posquit0/koa-rest-api-boilerplate" rel="noopener noreferrer"&gt;posquit0/koa-rest-api-boilerplate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/inadarei/maikai" rel="noopener noreferrer"&gt;inadarei/maikai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/banzaicloud/service-tools" rel="noopener noreferrer"&gt;banzaicloud/service-tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[transitive-bullshit/koa-micro][transitive]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/kachiic/koa-js-part-1-how-to-make-a-koa-server-in-10-minutes-3og9"&gt;Koa Js : Part 1 - How to make a Koa server in 10 minutes!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sentry.io/platforms/node/guides/koa/" rel="noopener noreferrer"&gt;Sentry's Koa Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Health check

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dyhpoon/koa-simple-healthcheck" rel="noopener noreferrer"&gt;dyhpoon/koa-simple-healthcheck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rictorres/koa-ping-healthcheck" rel="noopener noreferrer"&gt;rictorres/koa-ping-healthcheck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Docker

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/" rel="noopener noreferrer"&gt;Best practices for writing Dockerfiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/" rel="noopener noreferrer"&gt;Snyk's 10 best practices to containerize Node.js web applications with Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/techworld_with_nana/top-8-docker-best-practices-for-using-docker-in-production-1m39"&gt;Top 8 Docker Best Practices for using Docker in Production ✅&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hexops/dockerfile" rel="noopener noreferrer"&gt;hexops/dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>node</category>
      <category>beginners</category>
      <category>koa</category>
    </item>
    <item>
      <title>Agile Improv</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Tue, 12 Jan 2021 13:05:08 +0000</pubDate>
      <link>https://forem.com/jolanglinais/agile-improv-4m0i</link>
      <guid>https://forem.com/jolanglinais/agile-improv-4m0i</guid>
      <description>&lt;h2&gt;
  
  
  The Principles of Improv
&lt;/h2&gt;

&lt;p&gt;One of the things I miss most in quarantine is going to see live improv comedy. As often as I could, I used to go see shows at New York City’s &lt;a href="https://en.wikipedia.org/wiki/Upright_Citizens_Brigade_Theatre" rel="noopener noreferrer"&gt;Upright Citizen’s Brigade&lt;/a&gt; theater and lose my mind laughing at the incredibly talented improvisers there. I even took a few improv classes to try it out myself. On top of being painfully funny, improv has taught me lessons about communication, teamwork, and creativity that I’ve found extremely helpful to apply to my work in software engineering.&lt;/p&gt;

&lt;p&gt;Improv isn’t easy, but its principles are simple. The only rules are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Listen&lt;/li&gt;
&lt;li&gt;Say yes&lt;/li&gt;
&lt;li&gt;Advance the scene&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Listen
&lt;/h3&gt;

&lt;p&gt;Active listening is an underrated and undervalued skill. We all know we should do it, but oftentimes we’re merely waiting for our turn to speak or rushing to assert our own ideas. Improvisation emphasizes paying attention, staying present, and interpreting intent.&lt;/p&gt;

&lt;p&gt;Listening to your teammates is perhaps the most important part of improv. Stephen Colbert, who got his start in improv, said: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;There are very few rules to improvisation, but one of the things I was taught early on is that you are not the most important person in the scene. Everybody else is. And if they are the most important people in the scene, you will naturally pay attention to them and serve them.&lt;/em&gt;”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Serving your fellow improvisers—or, in this case, your colleagues—requires setting aside ego, embracing humility, and placing trust in others.&lt;/p&gt;

&lt;p&gt;In improv, neglecting to listen to a fellow performer means the scene won’t make sense. In programming, neglecting to listen to a coworker leads to missing valuable context or information, which often leads to making incorrect assumptions and even taking unnecessary risks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Say yes
&lt;/h3&gt;

&lt;p&gt;Improvisers avoid choices that hinder progress such as discouraging their teammates, shooting down ideas, or being contrarian. Instead, they make a habit of accepting the reality with which they are presented.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Agile_software_development" rel="noopener noreferrer"&gt;Agile&lt;/a&gt; method of software engineering is a world-building exercise that is, in some ways, uncannily similar to improv. It advocates for responding to change rather than &lt;a href="https://en.wikipedia.org/wiki/Waterfall_model" rel="noopener noreferrer"&gt;following a plan&lt;/a&gt; and it values individuals and interactions over processes and tools. Its reaction-and-response approach generates solutions that likely could not have been predicted at the beginning of the process.&lt;/p&gt;

&lt;p&gt;Many of the skills valued by both improv and Agile come into play during the brainstorming process. A brainstorming session among colleagues requires a back-and-forth exchange of ideas and feedback. Programming is only possible when engineers are open to hearing new ideas—coding cannot progress if proposals are always struck down.&lt;/p&gt;

&lt;p&gt;Saying yes to an idea does not necessarily mean endorsing it as a &lt;em&gt;great&lt;/em&gt; idea; it only means accepting the idea as valid and following it to see where it may lead. No idea is great in and of itself—rather, a collection or evolution of ideas and the changes that result from them can lead to something great. Great results can emerge even from poor suggestions. Even if suggestions don’t end up working out, making a habit of exploring them encourages collaborative sharing of ideas.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Advance the scene
&lt;/h3&gt;

&lt;p&gt;At its core, improv is not actually about making jokes or being funny—it’s about cooperative creation. When people step outside their comfort zones and let go of their limiting assumptions, rather than being critical or analytical, it enables a connection between them that leads to building, development, and invention.&lt;/p&gt;

&lt;p&gt;There is a concept in improv called &lt;strong&gt;finding the game&lt;/strong&gt;, which means finding the crux, the pattern, the thing that is interesting or funny about a scene. The UCB Theatre’s motto is Si haec insolita res vera est, quid exinde verum est?: “&lt;em&gt;If this unusual thing is true, what else is true?&lt;/em&gt;” An improviser finds the game of the scene by identifying what is weird/remarkable/funny, then taking action to follow the implications to their natural, and often comical, results.&lt;/p&gt;

&lt;p&gt;In software engineering, finding the game is analogous to problem-solving. When solving a technical issue, you have to identify a bug or roadblock before you can resolve it. This requires tackling challenges with creativity, flexibility, and open-mindedness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes As Opportunities
&lt;/h2&gt;

&lt;p&gt;Veteran improviser Colin Mochrie said: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;Embracing failure is one of the beautiful things about improv. If the scene is going well, great. But if something goes wrong, sometimes it can be even better. So, it’s just basically relaxing and dealing with whatever is going wrong at that point.&lt;/em&gt;”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In coding, like in improv (and everything else in life), mistakes are inevitable. Judging those who fail, including (and especially) yourself, is neither kind nor productive. Pushing past the discomfort of failure is essential for growth, and mistakes can often lead to revelatory discoveries.&lt;/p&gt;

&lt;p&gt;A supportive, encouraging workplace environment is one in which the whole team is thought to have collective ownership over the project—that means the successes as well as the failures. This is why a blameless culture is ideal, especially in &lt;a href="https://www.atlassian.com/incident-management/postmortem/blameless" rel="noopener noreferrer"&gt;postmortems&lt;/a&gt;. Blame is a variation of saying, "no": we cannot say what someone did was not supposed to happen because there is no such thing in reality as 'supposed to happen'. Blame is a wasted effort, like regret. In a culture where mistakes are forgiven, these experiences become lessons learned. Embracing a challenge turns an obstacle into an opportunity.&lt;/p&gt;

&lt;p&gt;Improv host Aisha Tyler also attested to the valuable lessons taught by failure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;Killing doesn’t make you funny. It’s only bombing that makes you funny. […] When you bomb, you really have to reexamine every creative choice you’ve made and think about if it was the right one.&lt;/em&gt;”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Play
&lt;/h2&gt;

&lt;p&gt;A tendency to overthink or overanalyze can cause work to feel chronically stressful. While there is a time and place for intense critical thought, improv provides a framework for avoiding analysis paralysis.&lt;/p&gt;

&lt;p&gt;Experience allows for handling the unexpected with grace and competency. Just as improv scenes need to build gradually with solid development of characters and relationships, coding solutions should not be rushed in sacrifice of a good foundation. They both require patience and frustration tolerance.&lt;/p&gt;

&lt;p&gt;Remaining playful and loose allows for quick reactions and prevents you from being left behind the action. If an improviser is in their head, they aren’t paying attention to what is happening. If an engineer is too busy planning, they aren’t responding appropriately to changes in real time.&lt;/p&gt;

&lt;p&gt;While thoughtful, deliberate action is ideal, environments and situations are always changing in the chaotic real world. Improv thrives on making sense of what is happening at the speed of thought. Likewise, there is no perfect or static software; it changes incessantly in response to continuously changing circumstances. An engineer in Agile is quickly iterating on making sense of a changing landscape.&lt;/p&gt;

&lt;p&gt;An improviser steps out on stage with only a few seconds’ worth of an idea in mind, never a whole scene. Similarly, no engineer begins with a flawless start-to-finish plan fully mapped out in their head. It takes the whole team to make a show.&lt;/p&gt;

&lt;p&gt;This is the human element shared by improv, programming, and any other collaborative team endeavor. Humans are not machines: we thrive on connection, interaction, and relationships. We work best when we embrace playfulness and fun. &lt;/p&gt;

&lt;p&gt;Fun is fun because it is in-the-moment, free from domination of the over-analytical brain. Being in the moment feels liberating. It can be freeing to accept that you do not know what will happen next, to let go of expectations for how things are “supposed to” go.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>watercooler</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JavaScript Utility Libraries</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Tue, 29 Dec 2020 18:26:20 +0000</pubDate>
      <link>https://forem.com/jolanglinais/javascript-utility-libraries-ef2</link>
      <guid>https://forem.com/jolanglinais/javascript-utility-libraries-ef2</guid>
      <description>&lt;h1&gt;
  
  
  Comparison of JS, Ramda, and Lodash
&lt;/h1&gt;

&lt;p&gt;With &lt;a href="https://tc39.es/ecma262/" rel="noopener noreferrer"&gt;&lt;em&gt;ECMAScript 2020&lt;/em&gt;&lt;/a&gt; available, external libraries are not necessary for functional programming (FP) - specifically currying and composition. The two main libraries for this kind of work have been &lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;Ramda&lt;/a&gt; and &lt;a href="https://github.com/lodash/lodash/wiki/FP-Guide" rel="noopener noreferrer"&gt;Lodash FP&lt;/a&gt;. &lt;a href="https://underscorejs.org/" rel="noopener noreferrer"&gt;UnderscoreJS&lt;/a&gt; is another, but Lodash is generally thought of as an improvement on this library. Lodash is a fork of Underscore, and the &lt;a href="https://stackoverflow.com/a/13898916" rel="noopener noreferrer"&gt;history of why it forked&lt;/a&gt; is rather interesting.&lt;/p&gt;

&lt;p&gt;However, it can still be a good idea to use one of these tried-and-tested libraries for more complex situations with FP. If these complex scenarios are not being taken advantage of, vanilla JavaScript can keep up with utility libraries for the most part. Some notable exceptions would be &lt;code&gt;debounce&lt;/code&gt; from &lt;a href="https://lodash.com/" rel="noopener noreferrer"&gt;Lodash&lt;/a&gt; and &lt;code&gt;merge&lt;/code&gt; from Ramda.&lt;/p&gt;

&lt;p&gt;To reiterate, a lot of the benefits that lead to the use of Ramda and Lodash have been baked into vanilla JavaScript. Arrow functions allow for a version of currying, and along with chaining functions, can adequately compose functions. Similarly, prototypal methods are being added every version which makes Lodash less and less useful.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: Arrow functions don't allow for &lt;em&gt;actual&lt;/em&gt; currying (&lt;code&gt;(a, b) =&amp;gt; {}&lt;/code&gt; is the same as &lt;code&gt;a =&amp;gt; b =&amp;gt; {}&lt;/code&gt;, i.e. the function itself tracks how many of its arguments have been defined), just quite close.&lt;/p&gt;

&lt;p&gt;This article will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give a brief overview of Ramda and Lodash (FP)&lt;/li&gt;
&lt;li&gt;Note the cases in which it makes sense to invest in the library or not&lt;/li&gt;
&lt;li&gt;Give context to a few methods which stand out&lt;/li&gt;
&lt;li&gt;Provide a table summary for which library is better in which regard&lt;/li&gt;
&lt;li&gt;Provide a &lt;a href="https://repl.it/@irmerk/Comparing-Utility-Libraries" rel="noopener noreferrer"&gt;&lt;strong&gt;REPL&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://github.com/irmerk/javascript-utilities-ramda-lodash" rel="noopener noreferrer"&gt;&lt;strong&gt;repository&lt;/strong&gt;&lt;/a&gt; for generating benchmarks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this being public means you are free to contribute to the list and make adjustments&lt;/p&gt;

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

&lt;p&gt;As previously stated, native JavaScript has become &lt;em&gt;quite&lt;/em&gt; a bit more powerful over the past few years. While helper and utility libraries are still helpful, most everything in them can be reduced down to some combination of &lt;code&gt;filter()&lt;/code&gt;, &lt;code&gt;map()&lt;/code&gt;, and &lt;code&gt;reduce()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I write more at length in my &lt;a href="https://dev.to/irmerk/modern-javascript-techniques-4chc"&gt;Modern Javascript Techniques&lt;/a&gt; article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Functionality needed is straightforward, with few steps or transformations needed&lt;/li&gt;
&lt;li&gt;Complex functionality needing a few extra steps is not a deterrent&lt;/li&gt;
&lt;li&gt;Bundle size being important&lt;/li&gt;
&lt;li&gt;Learning the process that goes into these simplified helper functions from other libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ramda
&lt;/h2&gt;

&lt;p&gt;Ramda emphasizes a purer functional style, with immutability and side-effect free functions being at the heart of the design philosophy. Ramda is about &lt;em&gt;transforming&lt;/em&gt; data and &lt;em&gt;composing&lt;/em&gt; functions. This is why things like &lt;code&gt;throttle&lt;/code&gt; and &lt;code&gt;debounce&lt;/code&gt; are not supported because they involve side-effects. To achieve this in a pure way, &lt;a href="https://en.wikipedia.org/wiki/Functional_reactive_programming" rel="noopener noreferrer"&gt;functional reactive programming&lt;/a&gt; would be required to abstract over this with event streams.&lt;/p&gt;

&lt;p&gt;Ramda functions are &lt;em&gt;automatically&lt;/em&gt; curried. This allows for easily building up new functions from old ones by not supplying the final parameters. The parameters to Ramda functions are arranged to make it convenient for currying. The data to be operated on is generally supplied last. These last two points together make it very easy to build functions as sequences of simpler functions, each of which transforms the data and passes it along to the next. Ramda is designed to support this style of coding.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ramda provides several functions that return problematic values such as &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;Infinity&lt;/code&gt;, or &lt;code&gt;NaN&lt;/code&gt; when applied to unsuitable inputs. These are known as &lt;a href="https://en.wikipedia.org/wiki/Partial_function" rel="noopener noreferrer"&gt;partial functions&lt;/a&gt;. Partial functions necessitate the use of guards or null checks.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A remedy for this could be &lt;a href="https://sanctuary.js.org/" rel="noopener noreferrer"&gt;Sanctuary&lt;/a&gt;, a JavaScript functional programming library inspired by &lt;a href="https://www.haskell.org/" rel="noopener noreferrer"&gt;Haskell&lt;/a&gt; and &lt;a href="http://www.purescript.org/" rel="noopener noreferrer"&gt;PureScript&lt;/a&gt;. It's stricter than Ramda, and provides a similar suite of functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Composition, taking data last and always currying&lt;/li&gt;
&lt;li&gt;Specific methods, typically involving complex operations, e.g. &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;assoc&lt;/code&gt;, &lt;code&gt;pluck&lt;/code&gt;...&lt;/li&gt;
&lt;li&gt;Similar common methods used in multiple places&lt;/li&gt;
&lt;li&gt;Complex, non-linear composition by using &lt;code&gt;R.converge()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lodash
&lt;/h2&gt;

&lt;p&gt;There's little to go into here. Lodash is an extremely performant utility library. While bundle size has been an issue in the past, Lodash has become much more modularized in format. This enables build tools like webpack and parcel to do tree-shaking and removing any unused functions, which reduces bundle size.&lt;/p&gt;

&lt;p&gt;Keep in mind that there are many functions which &lt;a href="https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore" rel="noopener noreferrer"&gt;can be done natively&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: While Lodash appears faster in the benchmarks below with the &lt;code&gt;_.toString()&lt;/code&gt; method, the results were actually not identical to the same functions in JS and Ramda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;debounce&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Similar common methods used in multiple places&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lodash FP
&lt;/h3&gt;

&lt;p&gt;Lodash provides &lt;code&gt;lodash/fp&lt;/code&gt;, a module to promote a more functional programming style. This module allows for curried versions of the Lodash functions.  This makes Lodash a good alternative to Ramda.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Composition, taking data last and always currying&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Benchmark Results
&lt;/h1&gt;

&lt;p&gt;Note that I have begun this list with common methods I and my team use, and it is in no means exhaustive. Please feel free to look into the &lt;a href="https://github.com/irmerk/javascript-utilities-ramda-lodash" rel="noopener noreferrer"&gt;repository&lt;/a&gt; and open a pull request to add further methods or tests.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Readability&lt;/th&gt;
&lt;th&gt;Does Have&lt;/th&gt;
&lt;th&gt;Does Not Have&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Symbols&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Javascript&lt;/th&gt;
&lt;th&gt;Lodash&lt;/th&gt;
&lt;th&gt;Ramda&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Downloads (week)&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;41,323,748&lt;/td&gt;
&lt;td&gt;7,952,372&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (unpacked)&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;1.41 MB&lt;/td&gt;
&lt;td&gt;1.07 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (minified)&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;69.9 kB&lt;/td&gt;
&lt;td&gt;53.4 kB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size (mini+gzip)&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;24.4 kB&lt;/td&gt;
&lt;td&gt;12.4 kB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Download Time&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;488 ms&lt;/td&gt;
&lt;td&gt;247 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Issues&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;211&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Last Publish&lt;/td&gt;
&lt;td&gt;N/A ✅&lt;/td&gt;
&lt;td&gt;4 month&lt;/td&gt;
&lt;td&gt;5 month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FEATURES&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curry&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Immutable&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chainable&lt;/td&gt;
&lt;td&gt;Yes ✅&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functional&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SECURITY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Known Issues&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;a href="https://snyk.io/advisor/npm-package/lodash" rel="noopener noreferrer"&gt;Yes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://snyk.io/advisor/npm-package/ramda" rel="noopener noreferrer"&gt;No&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependencies&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;COMMON METHODS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Arrays&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;each&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;findIndex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;flatten&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fromPairs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pluck&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;range&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniq&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Objects&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;assoc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;keys&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;merge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;omit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pick&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toPairs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;values&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zipObj&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Strings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;toString&lt;/code&gt; array&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;toString&lt;/code&gt; object&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;toString&lt;/code&gt; date&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;split&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toLower&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;toUpper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Utility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;clone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵🔶&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;debounce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isEmpty&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isEqual&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isFunction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isNil&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Composition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Numbers&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Objects&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functional&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overall&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;🔵&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Totals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;16&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;21&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test: Arrays and Collections&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;JS Time (ms)&lt;/th&gt;
&lt;th&gt;_ Time [ms]&lt;/th&gt;
&lt;th&gt;R Time [ms]&lt;/th&gt;
&lt;th&gt;Diff to JS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;concat&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;+83%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;each&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;+93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;filter&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;+19%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;find&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;+35%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;findIndex&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;+58%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flatten (deep)&lt;/td&gt;
&lt;td&gt;1438&lt;/td&gt;
&lt;td&gt;174&lt;/td&gt;
&lt;td&gt;1937&lt;/td&gt;
&lt;td&gt;+156%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fromPairs&lt;/td&gt;
&lt;td&gt;531&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;513&lt;/td&gt;
&lt;td&gt;+3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fromPairs (reduce)&lt;/td&gt;
&lt;td&gt;542&lt;/td&gt;
&lt;td&gt;509&lt;/td&gt;
&lt;td&gt;510&lt;/td&gt;
&lt;td&gt;+6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;head&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;map&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;+50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;range&lt;/td&gt;
&lt;td&gt;533&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;62&lt;/td&gt;
&lt;td&gt;+176%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reduce&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;+128%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reject&lt;/td&gt;
&lt;td&gt;1263&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;+190%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tail&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;-100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;uniq&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;+22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zip&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test: Objects&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;JS Time (ms)&lt;/th&gt;
&lt;th&gt;_ Time [ms]&lt;/th&gt;
&lt;th&gt;R Time [ms]&lt;/th&gt;
&lt;th&gt;Diff to JS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;keys&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;800&lt;/td&gt;
&lt;td&gt;109&lt;/td&gt;
&lt;td&gt;+28%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;merge (triple)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;omit&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;+78%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;path (short)&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;-100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;path (long)&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;-66%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pick&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;-0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toPairs&lt;/td&gt;
&lt;td&gt;71&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;td&gt;+30%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;values&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;94&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;-139%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zipObj&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;121&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test: Strings&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;JS Time (ms)&lt;/th&gt;
&lt;th&gt;_ Time [ms]&lt;/th&gt;
&lt;th&gt;R Time [ms]&lt;/th&gt;
&lt;th&gt;Diff to JS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;toString (array) NOTE _&lt;/td&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;151&lt;/td&gt;
&lt;td&gt;2391&lt;/td&gt;
&lt;td&gt;-106%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString (object) NOTE _&lt;/td&gt;
&lt;td&gt;163&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;693&lt;/td&gt;
&lt;td&gt;+190%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString (date) NOTE _&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;-46%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;split&lt;/td&gt;
&lt;td&gt;592&lt;/td&gt;
&lt;td&gt;633&lt;/td&gt;
&lt;td&gt;601&lt;/td&gt;
&lt;td&gt;-1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLower&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;-0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toUpper&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;-7%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test: Utility&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;JS Time (ms)&lt;/th&gt;
&lt;th&gt;_ Time [ms]&lt;/th&gt;
&lt;th&gt;R Time [ms]&lt;/th&gt;
&lt;th&gt;Diff to JS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;clone&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;debounce&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isEmpty&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isEqual&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;106&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isFunction&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;isNil&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;type&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test: Totals&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;JS Time (ms)&lt;/th&gt;
&lt;th&gt;_ Time [ms]&lt;/th&gt;
&lt;th&gt;R Time [ms]&lt;/th&gt;
&lt;th&gt;Diff to JS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Curried / Piping Numbers&lt;/td&gt;
&lt;td&gt;1452&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2941&lt;/td&gt;
&lt;td&gt;+199%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curried / Piping Objects&lt;/td&gt;
&lt;td&gt;825&lt;/td&gt;
&lt;td&gt;1167&lt;/td&gt;
&lt;td&gt;748&lt;/td&gt;
&lt;td&gt;+9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curried / Piping FP&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;1094&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common Methods&lt;/td&gt;
&lt;td&gt;528&lt;/td&gt;
&lt;td&gt;554&lt;/td&gt;
&lt;td&gt;1155&lt;/td&gt;
&lt;td&gt;-4%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;Both Ramda and Lodash overlap, and should likely not be used in the same project. Depending on what data you're working on and which method you're using, these libraries can be very beneficial or unnecessary.&lt;/p&gt;

&lt;p&gt;An approach of &lt;strong&gt;Vanilla-JavaScript-First&lt;/strong&gt; should be taken, and these libraries shouldn't be used as a blanket approach to methods on data. Once you come across something that it is especially difficult to do in vanilla JavaScript, switch to one of these libraries. Which one? Comes down to taste. Both have a quite similar semantic style.&lt;/p&gt;

&lt;p&gt;Ramda is generally a better approach for functional programming as it was designed for this and has a community established in this sense.&lt;/p&gt;

&lt;p&gt;Lodash is generally better otherwise when needing specific functions (esp. &lt;code&gt;debounce&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Either way, &lt;strong&gt;ensure you invest in tree shaking&lt;/strong&gt; to minimize the bundle sizes of these libraries, because odds are you will only be using a few methods and do not need the entire library.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>functional</category>
      <category>ramda</category>
      <category>lodash</category>
    </item>
    <item>
      <title>GitHub Clones Replenish</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Sun, 06 Dec 2020 21:37:12 +0000</pubDate>
      <link>https://forem.com/jolanglinais/github-clones-replenish-1non</link>
      <guid>https://forem.com/jolanglinais/github-clones-replenish-1non</guid>
      <description>&lt;p&gt;This configuration helps make my consistent pulling of repositories from GitHub a bit easier. Especially so if repositories can frequently change names, or the list of all current repositories can change. &lt;/p&gt;

&lt;p&gt;I wrote a script to clone all (specific) repositories in an organization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;My setup is currently running macOS Catalina, using iTerm2 with Bash.&lt;/p&gt;

&lt;p&gt;You will need &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;&lt;code&gt;homebrew&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://stedolan.github.io/jq/" rel="noopener noreferrer"&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt;, and &lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;&lt;code&gt;gh&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

brew &lt;span class="nb"&gt;install &lt;/span&gt;jq

brew &lt;span class="nb"&gt;install &lt;/span&gt;gh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Operation
&lt;/h2&gt;

&lt;p&gt;For this configuration, ensure you're in the desired directory and this script exists in the directory. This will create a new directory (named the date, i.e. &lt;code&gt;2020-12-06T21:16:47Z&lt;/code&gt;) where you are, and then dump all the clones within that directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bash ./&amp;lt;SCRIPT_NAME&amp;gt;.sh INSERT_GITHUB_ORGANIZATION
&lt;span class="c"&gt;# bash ./replenishRepos.sh accordproject&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;h4&gt;
  
  
  All
&lt;/h4&gt;

&lt;p&gt;My configuration within this &lt;code&gt;scriptName.sh&lt;/code&gt; file in order to clone &lt;strong&gt;all&lt;/strong&gt; repositories within an organization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +&lt;span class="s2"&gt;"%Y-%m-%dT%H%M%SZ"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;gh api /orgs/&lt;span class="nv"&gt;$1&lt;/span&gt;/repos &lt;span class="nt"&gt;--paginate&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.[]'&lt;/span&gt; |  &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; &lt;span class="s1"&gt;'  '&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"## Cloning repositories"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;repo &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repositories&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# Cloning repo https://github.com/clauseHQ/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
  git clone &lt;span class="s2"&gt;"https://github.com/clauseHQ/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Specific
&lt;/h4&gt;

&lt;p&gt;My configuration within this &lt;code&gt;scriptName.sh&lt;/code&gt; file in order to clone &lt;strong&gt;only&lt;/strong&gt; repositories within an organization that have specific prefixes, are archived, and are private:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; +&lt;span class="s2"&gt;"%Y-%m-%dT%H%M%SZ"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;repositories&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;gh api /orgs/&lt;span class="nv"&gt;$1&lt;/span&gt;/repos &lt;span class="nt"&gt;--paginate&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.[] | select(.private == &amp;lt;BOOLEAN&amp;gt; and .archived == &amp;lt;BOOLEAN&amp;gt;) | .name | select(test("&amp;lt;PREFIX_1&amp;gt;") or test("&amp;lt;PREFIX_2&amp;gt;"))'&lt;/span&gt; |  &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; &lt;span class="s1"&gt;'  '&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"## Cloning repositories into &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENTDATE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;repo &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repositories&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# Cloning repo https://github.com/clauseHQ/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"####"&lt;/span&gt;
  git clone &lt;span class="s2"&gt;"https://github.com/clauseHQ/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.git"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this configuration, I can select archived or private repositories, and/or repositories with a specific prefix in the name.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>tutorial</category>
      <category>bash</category>
    </item>
    <item>
      <title>Shell CLI Readability</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Sun, 06 Dec 2020 20:08:37 +0000</pubDate>
      <link>https://forem.com/jolanglinais/bash-cli-readability-5882</link>
      <guid>https://forem.com/jolanglinais/bash-cli-readability-5882</guid>
      <description>&lt;p&gt;This configuration helps make my command line interface a bit more readable and increases the ease of use. It prevents from needing some consistent chores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running &lt;code&gt;pwd&lt;/code&gt; to see where you are&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;git status&lt;/code&gt; to see which branch you are in&lt;/li&gt;
&lt;li&gt;Investigating &lt;em&gt;when&lt;/em&gt; you ran that one command a while ago&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Zsh
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;My setup is currently running macOS Ventura, using &lt;a href="https://iterm2.com/" rel="noopener noreferrer"&gt;iTerm2&lt;/a&gt; with &lt;a href="https://en.wikipedia.org/wiki/Z_shell" rel="noopener noreferrer"&gt;Zsh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My command line appears as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybraoqwlrvzda6pmtgh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybraoqwlrvzda6pmtgh5.png" alt="My Zsh Shell Command Prompt" width="744" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is showing the current date and which directory I am in, as well as the git branch (if this is a git repository):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;DATE&amp;gt;@&amp;lt;TIME&amp;gt;[&amp;lt;WORKING_DIRECTORY&amp;gt;][&amp;lt;GIT_BRANCH&amp;gt;]:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;This customization can be done by editing an existing &lt;code&gt;~/.zshrc&lt;/code&gt; file or creating one. My current &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;autoload &lt;span class="nt"&gt;-Uz&lt;/span&gt; vcs_info
precmd_vcs_info&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; vcs_info &lt;span class="o"&gt;}&lt;/span&gt;
precmd_functions+&lt;span class="o"&gt;=(&lt;/span&gt; precmd_vcs_info &lt;span class="o"&gt;)&lt;/span&gt;
setopt prompt_subst
zstyle &lt;span class="s1"&gt;':vcs_info:git:*'&lt;/span&gt; formats &lt;span class="s1"&gt;'%b'&lt;/span&gt;

&lt;span class="nv"&gt;PROMPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'%F{#FE9A0A}%D%f%F{#09CAFF}@%f%T[%F{#0165F5}%~%f[%F{#78D236}${vcs_info_msg_0_}%f]: '&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First section is for loading the version control system (git in this case) and displaying the branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt Options
&lt;/h3&gt;

&lt;p&gt;Within the prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;%F{}...%f&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This formatting indicates the text in the &lt;code&gt;...&lt;/code&gt; area will be of the color within the &lt;code&gt;{}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;%F{#FE9A0A}%D%f&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;%D&lt;/code&gt; indicates a date format of &lt;code&gt;YY-MM-DD&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;%F{#09CAFF}@%f&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This is only the character &lt;code&gt;@&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;%T&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Indicates the 24 hour time in format &lt;code&gt;HH:MM&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;[&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This is only the character &lt;code&gt;[&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;code&gt;%F{#0165F5}%~%f&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;][&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This is only the characters &lt;code&gt;][&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;%F{#78D236}${vcs_info_msg_0_}%f&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;${vcs_info_msg_0_}&lt;/code&gt; will display the current git branch&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;]:&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;This is only the characters &lt;code&gt;]:&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Bash
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;My setup is currently running macOS Catalina, using &lt;a href="https://iterm2.com/" rel="noopener noreferrer"&gt;iTerm2&lt;/a&gt; with &lt;a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)" rel="noopener noreferrer"&gt;Bash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My command line appears as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fecmqaemiedys4dvpzac1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fecmqaemiedys4dvpzac1.png" alt="Alt Text" width="800" height="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is showing the current date and which directory I am in, as well as the git branch (if this is a git repository):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;06.12.2020@13:50[current-directory][git-branch-name]:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;This customization can be done by editing an existing &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt; file, or creating one. This file needs to export &lt;code&gt;PS1&lt;/code&gt;, which is the primary prompt. My current &lt;code&gt;~/.bash_profile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# get current branch in git repo&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;parse_git_branch&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;git branch 2&amp;gt; /dev/null | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'/^[^*]/d'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'s/* \(.*\)/\1/'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;STAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;parse_git_dirty&lt;span class="sb"&gt;`&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BRANCH&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;STAT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# get current status of git repo&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;parse_git_dirty &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;git status 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;dirty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"modified:"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;untracked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Untracked files"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;ahead&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Your branch is ahead of"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;newfile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"new file:"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;renamed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"renamed:"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;deleted&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt; /dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"deleted:"&lt;/span&gt; &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;renamed&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ahead&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newfile&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"+&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;untracked&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"?&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;deleted&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"x&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dirty&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"!&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
    if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;bits&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[38;5;214m&lt;/span&gt;&lt;span class="se"&gt;\]\D&lt;/span&gt;&lt;span class="s2"&gt;{%d.%m.%Y}&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[36m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[m&lt;/span&gt;&lt;span class="se"&gt;\]\A\[\e&lt;/span&gt;&lt;span class="s2"&gt;[m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[38;5;63m&lt;/span&gt;&lt;span class="se"&gt;\]\W\[\e&lt;/span&gt;&lt;span class="s2"&gt;[m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;]&lt;/span&gt;&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="s2"&gt;[38;5;82m&lt;/span&gt;&lt;span class="se"&gt;\]\`&lt;/span&gt;&lt;span class="s2"&gt;parse_git_branch&lt;/span&gt;&lt;span class="se"&gt;\`\[\e&lt;/span&gt;&lt;span class="s2"&gt;[m&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;: "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;parse_git_dirty&lt;/code&gt; function will cause the &lt;code&gt;...[git-branch-name]&lt;/code&gt; section of my prompt to include the following optional characters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt;: This branch is ahead of &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt;: A new file exists in this branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;?&lt;/code&gt;: Untracked files exist in this branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt;: Files have been deleted from this branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!&lt;/code&gt;: Files have been modified in this branch&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prompt Options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;\d&lt;/code&gt;: Date in “Weekday Month Date” format (e.g., &lt;code&gt;Tue May 26&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\D{format}&lt;/code&gt;: Date in format passed in&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\j&lt;/code&gt;: Number of jobs currently managed by the shell&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\l&lt;/code&gt;: Basename of the shells terminal device&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\n&lt;/code&gt;: Newline&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\s&lt;/code&gt;: Name of the shell&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\t&lt;/code&gt;: Current time in 24-hour &lt;code&gt;HH:MM:SS&lt;/code&gt; format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\T&lt;/code&gt;: Current time in 12-hour &lt;code&gt;HH:MM:SS&lt;/code&gt; format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\@&lt;/code&gt;: Current time in 12-hour &lt;code&gt;am/pm&lt;/code&gt; format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\A&lt;/code&gt;: Current time in 24-hour &lt;code&gt;HH:MM&lt;/code&gt; format&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\u&lt;/code&gt;: Username of the current user&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\w&lt;/code&gt;: Current working directory (&lt;code&gt;$HOME&lt;/code&gt; is represented by &lt;code&gt;~&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\W&lt;/code&gt;: Basename of the working directory (&lt;code&gt;$HOME&lt;/code&gt; is represented by &lt;code&gt;~&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\!&lt;/code&gt;: History number of this command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\#&lt;/code&gt;: Command number of this command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\$&lt;/code&gt;: Specifies whether the user is root (&lt;code&gt;#&lt;/code&gt;) or otherwise (&lt;code&gt;$&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\\&lt;/code&gt;: Backslash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\[&lt;/code&gt;: Start a sequence of non-displayed characters (useful if you want to add a command or instruction set to the prompt)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\]&lt;/code&gt;: Close or end a sequence of non-displayed characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that my &lt;code&gt;PS1&lt;/code&gt; includes the following sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Orange&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;38&lt;span class="p"&gt;;&lt;/span&gt;5&lt;span class="p"&gt;;&lt;/span&gt;214m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Date, in format&lt;/span&gt;
&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;%d.%m.%Y&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# Teal&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;36m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# @ symbol&lt;/span&gt;
@
&lt;span class="c"&gt;# Plain color&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Time, 24hr format&lt;/span&gt;
&lt;span class="se"&gt;\A&lt;/span&gt;
&lt;span class="c"&gt;# Plain color&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Open bracket symbol&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
&lt;span class="c"&gt;# Blue&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;38&lt;span class="p"&gt;;&lt;/span&gt;5&lt;span class="p"&gt;;&lt;/span&gt;63m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Current directory, not path&lt;/span&gt;
&lt;span class="se"&gt;\W&lt;/span&gt;
&lt;span class="c"&gt;# Plain color&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Close bracket symbol&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="c"&gt;# Green&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;38&lt;span class="p"&gt;;&lt;/span&gt;5&lt;span class="p"&gt;;&lt;/span&gt;82m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Function to generate git branch&lt;/span&gt;
&lt;span class="se"&gt;\`&lt;/span&gt;parse_git_branch&lt;span class="se"&gt;\`&lt;/span&gt;
&lt;span class="c"&gt;# Plain color&lt;/span&gt;
&lt;span class="se"&gt;\[\e&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;m&lt;span class="se"&gt;\]&lt;/span&gt;
&lt;span class="c"&gt;# Colon symbol&lt;/span&gt;
: 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>bash</category>
      <category>linux</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Year One: Lessons Learned</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Tue, 18 Feb 2020 23:56:01 +0000</pubDate>
      <link>https://forem.com/jolanglinais/year-one-lessons-learned-16gb</link>
      <guid>https://forem.com/jolanglinais/year-one-lessons-learned-16gb</guid>
      <description>&lt;h1&gt;
  
  
  Setting
&lt;/h1&gt;

&lt;p&gt;Halfway through university, I was forced to drop out due to lack of funds. I then spent ten years cycling through different careers (or, perhaps more accurately, attempts at careers). Throughout that time, I worked multiple jobs that did not truly interest me, none of which were in tech. Moreover, I also came out as transgender and transitioned during that time. When I finally decided to try to enter the tech industry, it felt like there were countless barriers against me. However, I was able to complete a coding bootcamp program and get hired as a software engineer. This article is my attempt to catalog some of the most important lessons I learned over the last year: my first year in tech.&lt;/p&gt;




&lt;h1&gt;
  
  
  Work
&lt;/h1&gt;

&lt;h4&gt;
  
  
  Accept the Chaos: It’s a Feature, Not a Bug
&lt;/h4&gt;

&lt;p&gt;When I was first hired at my software engineering job, it was quite an adjustment. The pace, the process, and the style of workflow were all brand new to me.  Initially, my approach was to create a comprehensive layout for every aspect of a project: I hoped that this would allow me to conquer all possible uncertainties. Soon enough, I learned there’s a reason &lt;a href="https://www.geeksforgeeks.org/software-engineering-failure-of-waterfall-model/" rel="noopener noreferrer"&gt;the “&lt;em&gt;waterfall method&lt;/em&gt;” doesn’t work in software&lt;/a&gt;. I struggled with feeling that I wasn’t making progress and did not have a grip on what was going on in a project. However, I came to understand that learning and identifying obstacles &lt;em&gt;is&lt;/em&gt; progress. In fact, it’s the entire point. This is part of the reason &lt;a href="https://www.agilealliance.org/agile101/" rel="noopener noreferrer"&gt;Agile&lt;/a&gt; is such a widely used methodology: it enables me to adapt to changes on the go rather than attempt to stick to a rigid, linear plan.&lt;/p&gt;

&lt;p&gt;Struggling in this process is the point—and I sure got the point. At some point during my many career attempts, I got it into my head that struggle equals failure, but in reality, that couldn’t be further from the truth. This may be some remnants of working in physical labor for a large part of my life, but my new career involves &lt;em&gt;thinking&lt;/em&gt; and &lt;em&gt;strategy&lt;/em&gt; and, as such, it has required me to reframe my perception of progress and success. Working in physical labor jobs for a large part of my life, my managers instilled mantras into me like, “&lt;em&gt;If you have time to lean, you have time to clean.&lt;/em&gt;” In those types of jobs, it was understood that no physical labor being done means no work being done. In the last year, I had to become a lot more comfortable with taking time to research, talking to myself, asking others questions, going on a walk to think something over, or visually mapping something out to get a better grasp of it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Teamwork
&lt;/h4&gt;

&lt;p&gt;For the first time in my life, I’m in a career where I feel that my input is actually valued. Now, I feel empowered to express myself. I consistently speak up in discussions and meetings. I often bounce ideas off coworkers. It’s easy to forget to give other people feedback (especially praise) out loud in public, but I have learned how important it is to make a concerted effort to do so whenever possible.&lt;/p&gt;

&lt;p&gt;Software development is a team sport. Relying on and supporting each other is paramount. It is the same with code: it is only useful when others can understand it. After much frustration, I have grown to appreciate that code quality is a constant pursuit, but understandable code is the ultimate goal. Code that is “&lt;em&gt;inefficient&lt;/em&gt;” but easily comprehensible is infinitely better than super slick code that no one else can figure out.&lt;/p&gt;

&lt;h4&gt;
  
  
  Curing My Paranoia
&lt;/h4&gt;

&lt;p&gt;I’m incompetent. I’m a fraud. I try to blend in, but soon enough, I’ll be exposed and exiled. Everyone in the office can smell my fear. They won’t fall for my act much longer. My manager and my coworkers frequently check in with me and assure me that they want to help, but I know better—they’re hoping I’ll fail. I must instantly know everything. Making a single mistake is unacceptable. I shouldn’t need to learn as I go. Without a doubt, my days at this job are numbered.&lt;/p&gt;

&lt;p&gt;…Unless I’m wrong. Imposter syndrome is a hell of a drug. &lt;/p&gt;

&lt;p&gt;For my own sanity, I try to remind myself that no one really knows what they are doing. It’s easy for me to assume everyone else knows exactly what is going on with everything, but the reality is that most people only understand a small &lt;em&gt;section&lt;/em&gt; of the technology we work with. Admitting ignorance can actually empower others: I know it makes me feel better.&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning from Others
&lt;/h4&gt;

&lt;p&gt;As a junior developer, I often face difficulty when trying to keep up with more senior coworkers. When I am pair programming with a more experienced developer, I tend to insist on “&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Pair_programming" rel="noopener noreferrer"&gt;driving&lt;/a&gt;&lt;/em&gt;.” This helps me control the pace and forces my partner to explain what they’re doing as we write our code together. I sometimes feel bad asking a ton of questions to gather more knowledge and context, but that is exactly what a junior should be doing. And patiently explaining is exactly what a senior should be doing. Remembering that helps relieve some of the imposter syndrome symptoms.&lt;/p&gt;

&lt;p&gt;Being close to an answer is not failure, but success. This was a hard lesson to learn. I ask to ensure I am on the right path quite regularly. All software is built by direct or indirect teams. Anyone who thinks otherwise is a &lt;a href="https://twitter.com/skirani/status/1149302828420067328" rel="noopener noreferrer"&gt;10x’r&lt;/a&gt; and should be backed away from slowly.&lt;/p&gt;

&lt;p&gt;One thing I love about the company I joined is that we emphasize teamwork and unity. Geographically, team members are spread out across two continents, but we invest in hosting several week-long in-person meetups each year. These have been instrumental in building team cohesion and chemistry, as well as giving me opportunities to develop interactive teaching sessions to knowledge share.&lt;/p&gt;




&lt;h1&gt;
  
  
  Self
&lt;/h1&gt;

&lt;h4&gt;
  
  
  Humility
&lt;/h4&gt;

&lt;p&gt;I have always tried to set aside my ego and admit when I don’t know something. In fact, after I was chosen for my job, I learned that my refreshing humility was one of the main reasons I was picked. In the last year, I have found that acknowledging my ignorance makes me feel more comfortable and reduces my imposter syndrome. I think my willingness to be honest about what I do and do not know, combined with my eagerness to learn, is one of the things that makes me a valuable employee. I try to stay humble by keeping in mind that there is always more to learn. &lt;/p&gt;

&lt;p&gt;A habit I have developed is to write down mistakes and wins in my notes a few times a week. This helps me to learn from my mistakes and combats imposter syndrome. Having a record of my accomplishments also helps me prepare for my bi-annual reviews.&lt;/p&gt;

&lt;h4&gt;
  
  
  Focus
&lt;/h4&gt;

&lt;p&gt;While I adapt to let go of my organizational approach to work, I strive to maintain my organization. It’s as confusing as it sounds. I am finding a balance of organizing logistics and tasks in a way which fits with an agile and ever-changing workflow.&lt;/p&gt;

&lt;p&gt;I aim to keep up to date on best practices to continually stay abreast with the industry standards. The job is to learn...which in itself is difficult to learn. I sometimes feel guilty about learning on the job, but I just have to remember, that is the job.&lt;/p&gt;

&lt;p&gt;I aspire to be well-rounded. Rather than become a specialist in one narrow field, or a generalist with no area of expertise, I aim to develop what can be called a &lt;a href="https://collegeinfogeek.com/become-t-shaped-person/" rel="noopener noreferrer"&gt;T-shaped skillset&lt;/a&gt;. I am not yet sure what the depth of that “&lt;strong&gt;T&lt;/strong&gt;” will be for me, but I am enjoying the journey toward discovering that.&lt;/p&gt;

&lt;p&gt;A thing that keeps me on track is focusing on the value I bring to the company. In the last year I have learned new ways to gauge my own worth. The company that I work for happens to be a lovely place that is staffed entirely of friendly and helpful people, but at the end of the day, a company is a company. The value I bring to that company constitutes my worth. This has served as a guiding principle for me when deciding where to focus my time and effort. For example, if I would like to make a feature that I think is interesting, but no one asked for it and no one wants it, then I am not adding value to the company. I would rather spend my energy contributing to a larger purpose. &lt;/p&gt;

&lt;h4&gt;
  
  
  Balance
&lt;/h4&gt;

&lt;p&gt;It has been hard for me to get in the habit of taking breaks, but nevertheless, I have found it to be immensely helpful. Overworking myself does no one any favors. It is better for both myself and my team to have a short day and then recuperate, rather than to power through the work day while feeling scatterbrained. Knowing this doesn’t always stop me from doing it, but I still try my best to work smarter, not harder. &lt;/p&gt;

&lt;p&gt;Burnout is real! Although I strive to maintain a workout routine and schedule plenty of physical activity outside of work, I frequently fail to stick to my goals. Attempting to balance my leisure activities with work has been an ongoing struggle. It is a work in progress that I hope to improve in my second year. &lt;/p&gt;




&lt;h1&gt;
  
  
  Taking Initiative
&lt;/h1&gt;

&lt;h4&gt;
  
  
  At Work
&lt;/h4&gt;

&lt;p&gt;Many of my learning opportunities over the last year came from extra duties that I took on at work. In my company, I became the unofficial advocate for git etiquette in our development workflow. I also became the main driver to consider implementing accessibility features into our products. I never specifically intended for this to become “&lt;em&gt;my thing&lt;/em&gt;” and I do worry about being pigeonholed into one particular role rather than growing in different directions. However, it is nice to have my own niche and to develop areas of expertise. &lt;/p&gt;

&lt;p&gt;One of the coolest opportunities has been to work on an open source project as a maintainer. Even if it weren’t part of my official job duties, I would still want to be involved in open source projects. I am passionate about making open source projects accessible to newcomers and have put a lot of work into making our project’s structure and documentation more approachable. This interest of mine culminated in our participation in &lt;a href="https://hacktoberfest.digitalocean.com/" rel="noopener noreferrer"&gt;Hacktoberfest&lt;/a&gt;, which was quite a huge undertaking. Just now I am applying to &lt;a href="https://summerofcode.withgoogle.com/" rel="noopener noreferrer"&gt;Google Summer of Code&lt;/a&gt;, and I have high hopes for that process turning out well.&lt;/p&gt;

&lt;h4&gt;
  
  
  Outside of Work
&lt;/h4&gt;

&lt;p&gt;I have made a specific effort to &lt;a href="https://www.swyx.io/writing/learn-in-public/" rel="noopener noreferrer"&gt;learn in public&lt;/a&gt; through blogging and public speaking. I try to write down what I learn and share it with others to spread the knowledge. It may feel obvious, but because it helped me, surely it can help others. I spent a large chunk of my first year’s free time writing articles and developing talks to present at meetups and conferences.&lt;/p&gt;

&lt;p&gt;I have also benefited from getting more personally involved in the tech community. Networking with others in the tech industry has exposed me to a huge range of learning opportunities. I have been a mentor as well as a mentee; both experiences have been invaluable in my education. &lt;/p&gt;

&lt;h4&gt;
  
  
  Making It My Own
&lt;/h4&gt;

&lt;p&gt;The great thing about this career compared to others in my past is that it is no longer about clocking in/tolerating the work/clocking out. In this job, I am actually engaged and invested in the work. I now have the freedom to go above and beyond the bare minimum expectations set for me by others. I work on projects that actually make sense to me. My company has a mission that actually speaks to me—I could even go so far as to say it inspires me. Coding and software engineering are brand new to me, yet somehow the work itself seems to fit me better than anything else I’ve tried. I feel that I have been given the chance to independently craft my own career, rather than simply just doing whatever work my boss orders me to do. In the old days, work was a chore that made me feel exploited; over the last year, I’ve learned what it feels like to have a job that gives me a sense of success and personal achievement. &lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Modern Javascript Techniques</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Wed, 28 Aug 2019 16:39:48 +0000</pubDate>
      <link>https://forem.com/jolanglinais/modern-javascript-techniques-4chc</link>
      <guid>https://forem.com/jolanglinais/modern-javascript-techniques-4chc</guid>
      <description>&lt;h2&gt;
  
  
  Clean and Scalable Syntax in Pursuit of Purity
&lt;/h2&gt;

&lt;p&gt;As a beautifully complex and adaptive language, &lt;em&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;&lt;/em&gt; has many advantages which grow every year. It is no wonder that the language and community is so extremely popular given that it had a large hand in bringing user interface interactivity and responsive web design to the internet. While sometimes complicated, the language proves to be easy to pick up and start, and allows for faster user experiences by being executed client-side.&lt;/p&gt;

&lt;p&gt;A large period of time saw JavaScript as problematic and flawed. This was never an issue with the language, but rather the platform it ran on: the browser. This ecosystem was flawed, as there were so many branching factions — most notably Microsoft coming in and mucking everything up. &lt;em&gt;&lt;a href="https://www.mozilla.org/en-US/" rel="noopener noreferrer"&gt;Mozilla&lt;/a&gt;&lt;/em&gt; was a voice of reason throughout this period, but it was not until Chrome gained enough market share to give incentive to realign people around a standard of how the engine should look and be built. Setting the standard with &lt;em&gt;&lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8&lt;/a&gt;&lt;/em&gt; is how &lt;em&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/em&gt; was subsequently built. As a full programming language with server side execution support, JavaScript now powers modern web applications and scales across the tech stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Approach
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvfvvmu7kmqvepby5mch2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvfvvmu7kmqvepby5mch2.png" alt="Accord Project Log" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My experience both as a maintainer of the  &lt;em&gt;&lt;a href="https://www.accordproject.org/" rel="noopener noreferrer"&gt;Accord Project&lt;/a&gt;&lt;/em&gt; , an open source project for smart legal contracts, and as a Full Stack Engineer has shown me the powerful applications in which JavaScript can be implemented. Moreover, I have become quite keen to learn and adopt better and more efficient practices within the language. I will be sharing this as both a useful reference for others, as well as a historical reference for myself in the future. I am hoping to branch off this to expand on topics covered in here in subsequent, deeper dive articles.&lt;/p&gt;

&lt;p&gt;The majority of our work at the Accord Project is in JavaScript , with some domain specific language mixed in. To architect a reliable tech stack which allows stability and efficiency for smart contracts, the Accord Project relies on JavaScript, as well as &lt;em&gt;&lt;a href="https://ocaml.org/" rel="noopener noreferrer"&gt;OCaml&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href="https://www.accordproject.org/projects/ergo" rel="noopener noreferrer"&gt;Ergo&lt;/a&gt;&lt;/em&gt;. JavaScript provides the best set of tools to handle this in a wide array of use cases and environments. We chose JavaScript because of its applicability, diversity of libraries, and ease of use. Syntax within this language is expressive yet simple.&lt;/p&gt;

&lt;p&gt;The Accord Project core codebase contains more than 250k lines of code. Along with our template library and UI components, there is near a million.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline:
&lt;/h2&gt;

&lt;p&gt;→ Approach&lt;br&gt;
→ Fundamentals&lt;br&gt;
→ Workflow&lt;br&gt;
→ Operations&lt;br&gt;
→ Functions&lt;br&gt;
→ Asynchronous&lt;br&gt;
→ Functional Programming&lt;br&gt;
→ Conclusion&lt;br&gt;
→ Resources&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Fundamentals
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Comprehensible
&lt;/h4&gt;

&lt;p&gt;Document code. Readability is paramount for programming, as it is humans who will need to interpret the code in order to collaborate. Being verbose enough to be legible at a later date or for another person is better practice than saving a few extra characters by naming variables with a single letter. Moreover, commenting and documentation - such as the &lt;em&gt;&lt;a href="https://devdocs.io/jsdoc/about-getting-started" rel="noopener noreferrer"&gt;JSDocs&lt;/a&gt;&lt;/em&gt; format - are extremely useful for building accessible code which can be shared with a team or others.&lt;/p&gt;

&lt;p&gt;It may seem redundant at first, but commenting code as best as possible will allow for easy refreshing through this built-in documentation months later when you circle back to a project or when pairing with a colleague.&lt;/p&gt;
&lt;h4&gt;
  
  
  Globals
&lt;/h4&gt;

&lt;p&gt;Avoid variables in the global scope. Multiple reasons exist for avoiding variables in the global scope. Performance is reduced due to function execution causing JavaScript to search through the scope change from in to out until it hits the global object. Furthermore, security flaws exist from this because functions can be invoked through the browser when they’re defined in the global space. This point will come up again in the functional programming section.&lt;/p&gt;
&lt;h4&gt;
  
  
  Variables
&lt;/h4&gt;

&lt;p&gt;Stop using &lt;code&gt;var&lt;/code&gt;. The scoping behavior is inconsistent and confusing, which can result in bugs. ES6 brought in &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;let&lt;/code&gt;.  Aim for using strictly &lt;code&gt;const&lt;/code&gt;, and only &lt;code&gt;let&lt;/code&gt; if that is not possible. There is more restriction and const is un-reassignable, but not quite immutable. The variable will have an unchanging reference to the same object or primitive value, but the value held by the variable is not immutable. Still, this will be best practice moving forward.&lt;/p&gt;
&lt;h4&gt;
  
  
  Naming
&lt;/h4&gt;

&lt;p&gt;A bit of digression, but programmers can expend 10x amounts of energy on naming conventions, yet struggle to be inclusive with their language. &lt;/p&gt;

&lt;p&gt;Taking the time to be descriptive and appropriate for legibility and comprehensive readability will do wonders in the future of the code. &lt;/p&gt;

&lt;p&gt;This is especially important for those looking to educate others; variable names should help explain and give context to what is happening in the code. Someone new to this code should be able to have a loose understanding of what is happening. Use verbs! An example for a Boolean variable could start with &lt;code&gt;is...&lt;/code&gt; and examples of functions could be action verbs.&lt;/p&gt;

&lt;p&gt;Good reference material can be found here: &lt;em&gt;&lt;a href="https://dev.to/somedood/a-grammar-based-naming-convention-13jf"&gt;A Grammar-Based Naming Convention&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Workflow
&lt;/h3&gt;

&lt;p&gt;A major key to maintainability is keeping logic in the right place and not cluttered or disorganized. The way a project or codebase is structured can make a large impact on how easy it is to understand and follow. &lt;/p&gt;
&lt;h4&gt;
  
  
  Importing Order
&lt;/h4&gt;

&lt;p&gt;Starting at a granular level, the order in which different modules are imported can reduce confusion by having a predictable pattern. The specific structure you use is less important than there being &lt;em&gt;some&lt;/em&gt; sort of structure:&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="cm"&gt;/* Packages */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prop-types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Styled Components */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;SC&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Components */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Navigation&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Actions */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ACT&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Utilities */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;navigateToClause&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utilities&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Modularization
&lt;/h4&gt;

&lt;p&gt;A goal to keep in mind is to keep packages, modules, functions, and scopes small. Reusability becomes much easier, as well as chaining, when this is in practice. Similar functions or those with many steps could be grouped into one module or class. Try to keep functions as simple as possible, and perform complex processes in steps.&lt;/p&gt;

&lt;p&gt;Once a file has grown above 300-400 lines of code, there is a strong case for being too cluttered and unmaintainable. At this point, a lot of benefit can be gained from creating new modules and folders to break up processes. Think of a project as a tree with many branches, rather than a mountain of heaped-up code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;&lt;/em&gt; is a great tool to help here. Aim for keeping files less than four or five indentations deep. This keeps code specialized and encourages cleanup of dead code. Several functions that do one small process will be more useful than one function which does several things. The large function can only be used in that one way, whereas smaller functions may be able to be used in multiple processes around a project. Exposing these smaller, helper functions creates a robust API base in a project.&lt;/p&gt;

&lt;p&gt;Great code can be improved upon without rewriting everything.&lt;/p&gt;

&lt;h4&gt;
  
  
  Isolate code
&lt;/h4&gt;

&lt;p&gt;A function &lt;em&gt;should&lt;/em&gt; have one purpose and not do multiple actions. That purpose &lt;em&gt;should&lt;/em&gt; be something other than a side effect, but we will circle back to this in functional programming section&lt;/p&gt;

&lt;p&gt;A contrived example of this is encapsulating conditionals:&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;// NO:&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&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;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parseErrors&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// YES:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorsExist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseErrors&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&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;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parseErrors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;errorsExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parseErrors&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Guard Clauses
&lt;/h4&gt;

&lt;p&gt;A great way to construct functions which have edge cases which result in an error or empty result is to have checks for these invalid results early. If this condition is not met or there is an invalid use case, then the bulk of the computation is prevented because we already know the result. This is referred to as the &lt;em&gt;&lt;a href="http://rikschennink.nl/thoughts/the-bouncer-pattern/" rel="noopener noreferrer"&gt;Bouncer Pattern&lt;/a&gt;&lt;/em&gt; or &lt;em&gt;&lt;a href="https://dev.to/lanecwagner/guard-clauses-how-to-clean-up-conditionals-2fdm"&gt;Guard Clauses&lt;/a&gt;&lt;/em&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;const&lt;/span&gt; &lt;span class="nx"&gt;parseContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&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;// Does a contract exist&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error, no contract!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Are there already parsed errors&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;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentErrors&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentErrors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Parse the contract&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clause&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;Not only will this optimize code, but will encourage thinking of functions and processes in a way which takes handling edge cases into consideration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prettier + Linting
&lt;/h4&gt;

&lt;p&gt;A theme to my article here is that code should be easy to read and understand. With that comes consistent styling and structuring. A linter - any linter - will be greatly useful. ESLint is a linter, and will identify issues with code correctness such as warning from using &lt;code&gt;var&lt;/code&gt;. &lt;em&gt;&lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt;&lt;/em&gt; is a formatter, which will identify issues with uniformity and consistency and automatically align brackets, for example. Using both in conjunction is encouraged.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://standardjs.com/" rel="noopener noreferrer"&gt;StandardJS&lt;/a&gt;&lt;/em&gt; and ESLint’s &lt;em&gt;&lt;a href="https://github.com/feross/eslint-config-standard" rel="noopener noreferrer"&gt;predefined config&lt;/a&gt;&lt;/em&gt; are good sources for linting rules if you need a good starting point.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Operations
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Destructuring
&lt;/h4&gt;

&lt;p&gt;Destructuring can help save a lot of typing and lines of code by keeping variables short and pulled from an object early on. Introduced with &lt;em&gt;&lt;a href="https://www.w3schools.com/js/js_es6.asp" rel="noopener noreferrer"&gt;ECMAScript 6&lt;/a&gt;&lt;/em&gt;, this allows access to specific fields from any object or module and immediately assign it to a variable.&lt;/p&gt;

&lt;p&gt;Objects:&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;// NO&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&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;clauses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clauses&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;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="nx"&gt;Cicero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// YES&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="nx"&gt;Cicero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&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;Arrays (skipping elements consist of &lt;code&gt;, ,&lt;/code&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;// NO&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lettersArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&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="s2"&gt;B&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="s2"&gt;C&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="s2"&gt;D&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="s2"&gt;E&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="s2"&gt;F&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;firstLetter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lettersArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// "A"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thirdLetter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lettersArray&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="c1"&gt;// "C"&lt;/span&gt;

&lt;span class="c1"&gt;// YES&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;firstLetter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thirdLetter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lettersArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// remaining = [ "D", "E", "F" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functions (similar to objects):&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;// NO&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Errors exist!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No clauses exist!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// YES&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&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;clauses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Errors exist!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No clauses exist!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Default Values
&lt;/h4&gt;

&lt;p&gt;When destructuring, there is an ability to assign default values to parameters. This can also indicate to the user what values can be passed in or are required.&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;generateText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Stock Contract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;English&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No text exists yet!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="nx"&gt;clauses&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Cicero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;clauses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&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;If no error should be thrown when a value is not passed, a default value could be useful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ternary
&lt;/h4&gt;

&lt;p&gt;This operator works similar to &lt;em&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators" rel="noopener noreferrer"&gt;logical operators&lt;/a&gt;&lt;/em&gt; and &lt;code&gt;if...else&lt;/code&gt; statements, and has three sections:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Boolean conditional&lt;/li&gt;
&lt;li&gt;Return value in case of truthy&lt;/li&gt;
&lt;li&gt;Return value in case of falsy
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// condition ? truthyResult : falsyResult&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorArrayLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;errorsExist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to steer clear of negative conditionals - check if something &lt;em&gt;does&lt;/em&gt; exist, rather than if it does not exist.&lt;/p&gt;

&lt;h4&gt;
  
  
  Spread
&lt;/h4&gt;

&lt;p&gt;Another form of object destructuring, the spread operator allows for value extraction from data without having to iterate over the data explicitly. This is common in &lt;em&gt;&lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt;&lt;/em&gt;  and functional programming, as it is a short way to add to an object without mutating it - copy an old object by spreading it and adding a new value to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstHalf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&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="s2"&gt;B&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="s2"&gt;C&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;secondHalf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D&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="s2"&gt;E&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="s2"&gt;F&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;lettersArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;firstHalf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;secondHalf&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// lettersArray = [ "A", "B", "C", "D", "E", "F" ];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No text exists yet!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contractWithClauses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;clauses&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Template Literals
&lt;/h4&gt;

&lt;p&gt;This feature allows for embedding dynamic content into strings and writing strings which bridge multiple lines. These are designated with backquotes and template literal snippets (&lt;code&gt;${}&lt;/code&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;// NO&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;contractTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contract Name: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, Errors: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&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;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// YES&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contractTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Contract Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Errors: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;

&lt;span class="c1"&gt;// OTHER USES&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;conditionalTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;contractExist&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Contract Name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No contract exists.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;multipleLines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Hello,

Good to meet you`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Functions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Limit Scope
&lt;/h4&gt;

&lt;p&gt;Functions &lt;em&gt;should&lt;/em&gt; do one thing. They become difficult to test and reason through once they begin performing multiple actions. Aim to have no more than one level of abstraction in functions - split functions up if necessary.&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;// NO&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&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;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&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;contractText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noErrors&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&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;// YES&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isContractValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&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;contractText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&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;contractText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noErrors&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;parseContract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contracts&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;contracts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isContractValid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Arrow
&lt;/h4&gt;

&lt;p&gt;This newer syntax for functions provides a concise and clear flow to the notation. These also have more practical scoping behavior by inheriting &lt;code&gt;this&lt;/code&gt; from the scope in which the function was defined in. &lt;/p&gt;

&lt;p&gt;Previously, a function would be written as:&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="nf"&gt;someFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// ... code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we define the same thing as:&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;someFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&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;// ... code&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the function is only returning something simple, we can write this in one line with an implicit &lt;code&gt;return&lt;/code&gt; statement:&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;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Parameters
&lt;/h4&gt;

&lt;p&gt;Aim for limiting the amount of parameters passed into a function to improve testability. Ideally, this would be below three. Usually, if there are three or more arguments, the function may be trying to do many things itself and should be split up and consolidated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chaining
&lt;/h4&gt;

&lt;p&gt;A source of current frustration comes from the inability to easily access a nested value within an object. Something like this may be used currently:&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;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondProp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thirdProp&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thirdProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fourthProp&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="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secondProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thirdProp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fourthProp&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hideous.&lt;/p&gt;

&lt;p&gt;The reason for doing this is if you go straight for the last line, you could run into this kind of error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;TypeError: Cannot &lt;span class="nb"&gt;read &lt;/span&gt;property ‘fourthProp’ of undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TC39 (the technical committee that determines what features become a part of the JavaScript standard) has moved the &lt;em&gt;&lt;a href="https://github.com/tc39/proposal-optional-chaining" rel="noopener noreferrer"&gt;Optional Chaining proposal&lt;/a&gt;&lt;/em&gt; the later stages of acceptance.&lt;/p&gt;

&lt;p&gt;I am really looking forward to this, because it would make the above code appear as such:&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;firstProp&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;secondProp&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;thirdProp&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;fourthProp&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&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;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;execute&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any property does not exist, the digging exits and returns &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another current solution to this is &lt;em&gt;&lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;Ramda&lt;/a&gt;&lt;/em&gt;, which uses a function called &lt;code&gt;path&lt;/code&gt; to safely execute code at run-time and not run into &lt;code&gt;undefined&lt;/code&gt; errors in the console.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Asynchronous
&lt;/h3&gt;

&lt;p&gt;I have previously written about &lt;em&gt;&lt;a href="https://dev.to/irmerk/asynchronous-with-redux-sagas-44dm"&gt;Asynchronous with Redux Sagas&lt;/a&gt;&lt;/em&gt;, but will be focusing more on &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; and promises for this.&lt;/p&gt;

&lt;p&gt;Asynchronous simply means things happen independently of the main program flow; computers are designed this way. A processor will not pause to wait for a side effect to happen to resume operations. JavaScript is synchronous by default and single threaded; code cannot run in parallel. However, JavaScript was designed to respond to user actions, which are asynchronous in nature. The browser, in which JavaScript lives, provides a set of APIs which handle this functionality. Moreover, &lt;em&gt;&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/em&gt; introduces a non-blocking I/O environment to extend this concept to files, network calls, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2FAsyncDiagram.jpg%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2FAsyncDiagram.jpg%3Fraw%3Dtrue" alt="Asynchronous vs. Synchronous" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When this side function is handed over to a separate thread, such as an API call., it returns as a callback, which is a function passed into another function as an argument. This is then invoked inside the outer function to complete an action.&lt;/p&gt;

&lt;h4&gt;
  
  
  Async + Await
&lt;/h4&gt;

&lt;p&gt;Previously, JavaScript relied on promises and callbacks for asynchronous code. This could easily result in &lt;em&gt;&lt;a href="https://blog.hellojs.org/asynchronous-javascript-from-callback-hell-to-async-and-await-9b9ceb63c8e8" rel="noopener noreferrer"&gt;Callback Hell&lt;/a&gt;&lt;/em&gt;. This syntactic sugar built on top of promises provides a much smoother way of handling asynchronous code, but cannot be used with plain callbacks or node callbacks. Now asynchronous code can be written more like synchronous code. Similar to promises, these are non-blocking.&lt;/p&gt;

&lt;p&gt;Functions which use this require the &lt;code&gt;async&lt;/code&gt; keyword before it, and &lt;code&gt;await&lt;/code&gt; can only be used in functions which have this keyword. This &lt;code&gt;async&lt;/code&gt; function implicitly returns a promise which will resolve to the value returned inside the 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="c1"&gt;// Promises&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outsideRequest&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="nf"&gt;retrieveData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;Executed&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Async/Await&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outsideRequest&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="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;retrieveData&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;Executed&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Clarity - Less code and more readable.&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Error handling - &lt;code&gt;try/catch&lt;/code&gt; can handle both synchronous and asynchronous code&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Conditionals - More straight forward handling of dynamic results&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Debugging - Error stack traces are much easier to track&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Await anything&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Functional Programming
&lt;/h3&gt;

&lt;p&gt;There are two major paradigms when it comes to programming, imperative and declarative. An imperative way to approach writing a function would be to explain each minute step of the process, whereas declarative takes the approach of expressing computational logic without describing specific flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imperative&lt;/strong&gt;: How to do something&lt;br&gt;
&lt;em&gt;Example&lt;/em&gt;: Instruct someone to bake a cake, step-by-step&lt;br&gt;
&lt;strong&gt;Declarative&lt;/strong&gt;: What to do&lt;br&gt;
&lt;em&gt;Example&lt;/em&gt;: Telling someone to bake a cake by describing a cake&lt;/p&gt;

&lt;p&gt;Functional programming is declarative. An intimidating and powerful programming paradigm, this treats computation as the evaluation of mathematical functions and avoids changing &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Program_state" rel="noopener noreferrer"&gt;state&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Immutable_object" rel="noopener noreferrer"&gt;mutable&lt;/a&gt;&lt;/em&gt; data. Functions are first class entities in JavaScript, which means they are treated as values and can be used as data. Functions can be referred to from constants and variables, be passed as a parameter to other functions, and be returned as a result of a function.&lt;/p&gt;

&lt;p&gt;In functional code, output values are contingent upon &lt;em&gt;only&lt;/em&gt; the arguments passed in, and will always result in the same value for the same input. Object-Oriented Programs, in contrast, can often depend on state and can produce different results at different times with the same arguments.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pure Functions
&lt;/h4&gt;

&lt;p&gt;A pure function is one which follows some guidelines of functional programming, namely it returns the same result given the same arguments (&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Idempotence" rel="noopener noreferrer"&gt;idempotent&lt;/a&gt;&lt;/em&gt;) and does not cause observable side effects. This makes it referentially transparent, and a benefit of this is that this code is much easier to test. With this concept, we are able to &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Memoization" rel="noopener noreferrer"&gt;memoize&lt;/a&gt;&lt;/em&gt; these functions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Side Effects
&lt;/h4&gt;

&lt;p&gt;Mutability is avoided in functional programming, and an example of this would be modifying the global object or a value in the global scope. Instead of mutating, functional programming aims to create new copies of data with additions or subtractions rather than mutating the original data.&lt;/p&gt;

&lt;p&gt;The main point is to avoid pitfalls like sharing state between objects or using mutable data that can be written to by anything. An action which is not pure, such as writing to a file, should be limited to one service which does it - minimize impure functionality.&lt;/p&gt;

&lt;p&gt;In JavaScript, primitive data types are passed by value, whereas objects are passed by reference. So if a function makes a change to an array, any other function which references that array will be affected. This is a huge danger that functional programming seeks to avoid; if two separate and unrelated functions take the same input, but one of the functions mutates that input, the other function is now flawed. It can become taxing to performance to be cloning large objects all the time, but there are great libraries which are quite performant, such as &lt;em&gt;&lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;Ramda&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ramda
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2Framda.jpg%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2Framda.jpg%3Fraw%3Dtrue" alt="Ramda.js" width="" height=""&gt;&lt;/a&gt;&lt;br&gt;
An excellent library which provides extra utility to functional programming in JavaScript, making it easier to create code pipelines. All functions are automatically curried, which makes this library extremely useful. Their wiki has a helpful section to help you find "&lt;em&gt;&lt;a href="https://github.com/ramda/ramda/wiki/What-Function-Should-I-Use" rel="noopener noreferrer"&gt;What Function Should I Use&lt;/a&gt;&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="http://www.sitepoint.com/currying-in-functional-javascript/" rel="noopener noreferrer"&gt;Currying&lt;/a&gt;&lt;/em&gt; gives us the ability to use higher order functions (ones which take functions as input and return functions) and closures to great effect.  Instead of a function with multiple arguments, a curried function would be one which takes a single argument and returns a function that takes a single argument. These are strung together to create a pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  Piping
&lt;/h4&gt;

&lt;p&gt;While Ramda is great for composing functions together in a pipe, JavaScript is a constantly evolving language and will soon have this natively.  TC39 currently has a proposal for a &lt;em&gt;Pipeline Operator&lt;/em&gt; &lt;em&gt;&lt;a href="https://github.com/tc39/proposal-pipeline-operator/wiki" rel="noopener noreferrer"&gt;Pipeline Operator&lt;/a&gt;&lt;/em&gt;. In the meantime, check out Ramda and find some really powerful tools!&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Conclusion
&lt;/h3&gt;

&lt;p&gt;The trope is old, criticism of JavaScript from many circles has lost merit. I suppose it is taking some 10x longer to get over their misgivings. This language has a high level of efficacy and is suitable for many environments and applications. There are a lot of exciting use cases all across technology, with the ability to touch the full stack. &lt;/p&gt;

&lt;p&gt;Gatekeeping and toxicity in this field aside, the ability to access so many different sectors provides for a more collaborative and better experienced population in the community. This language has &lt;em&gt;so much&lt;/em&gt; power. Cross platform desktop apps can be built with JavaScript in Electron, mobile apps with React Native, and server-side solutions with Node.js.&lt;/p&gt;

&lt;p&gt;While there is constant evolution to this language, there is not quite a new framework every week. Progression is good, and the community behind this language is quite progressive and innovative.&lt;/p&gt;

&lt;p&gt;Feel free to contact me with any questions or feedback.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Resources
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Community
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/t/javascript"&gt;DEV #javascript&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://javascriptweekly.com/" rel="noopener noreferrer"&gt;Javascript Weekly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Education
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://learn.freecodecamp.org/" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.khanacademy.org/computing/computer-programming" rel="noopener noreferrer"&gt;Khan Academy Computer Programming&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript" rel="noopener noreferrer"&gt;A Re-Introduction to JavaScript&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://javascript.info/" rel="noopener noreferrer"&gt;The Modern JavaScript Tutorial&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Books
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/getify/You-Dont-Know-JS" rel="noopener noreferrer"&gt;You Don’t Know JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://eloquentjavascript.net/" rel="noopener noreferrer"&gt;Eloquent Javascript&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Blogs
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@_ericelliott" rel="noopener noreferrer"&gt;Eric Elliott&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Podcasts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pca.st/m5IV" rel="noopener noreferrer"&gt;Javascript Jabber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/ijqf" rel="noopener noreferrer"&gt;JS Party&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/fmx9" rel="noopener noreferrer"&gt;Syntax.fm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/fullstack" rel="noopener noreferrer"&gt;Full Stack Radio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/ZD17" rel="noopener noreferrer"&gt;Ladybug Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/tr6K" rel="noopener noreferrer"&gt;Javascript to Elm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pca.st/i2d2" rel="noopener noreferrer"&gt;Elm Town&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Misc
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Bv_5Zv5c-Ts" rel="noopener noreferrer"&gt;JavaScript: Understanding the Weird Parts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;30 days of JavaScript challenges with corresponding videos by Wes Bos: &lt;a href="https://javascript30.com/" rel="noopener noreferrer"&gt;JS 30&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q/featured" rel="noopener noreferrer"&gt;Fun Fun Function&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Switch Case vs Object Literal:

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://medium.com/front-end-weekly/switch-case-if-else-or-a-lookup-map-a-study-case-de1c801d944" rel="noopener noreferrer"&gt;Switch case, if else or a loopup map by May Shavin&lt;/a&gt; &lt;/li&gt;
&lt;li&gt; &lt;a href="https://medium.com/chrisburgin/rewriting-javascript-replacing-the-switch-statement-cfff707cf045" rel="noopener noreferrer"&gt;Rewriting Javascript: Replacing the Switch Statement by Chris Burgin&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Static Typing

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Microsoft_TypeScript" rel="noopener noreferrer"&gt;TypeScript (TS)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/robertcoopercode/get-started-with-typescript-in-2019-6hd"&gt;Get Started With TypeScript in 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://scrimba.com/g/gintrototypescript" rel="noopener noreferrer"&gt;Gentle Intro To TypeScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://2ality.com/2018/04/type-notation-typescript.html" rel="noopener noreferrer"&gt;Understanding TypeScript’s type notation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Functional Frontend

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://guide.elm-lang.org/" rel="noopener noreferrer"&gt;Elm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elmprogramming.com/" rel="noopener noreferrer"&gt;Elm Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>beginners</category>
      <category>functional</category>
    </item>
    <item>
      <title>Asynchronous with Redux Sagas</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Fri, 16 Aug 2019 17:31:07 +0000</pubDate>
      <link>https://forem.com/jolanglinais/asynchronous-with-redux-sagas-44dm</link>
      <guid>https://forem.com/jolanglinais/asynchronous-with-redux-sagas-44dm</guid>
      <description>&lt;h3&gt;
  
  
  Sophisticated Side Effect Flow Management and Testing
&lt;/h3&gt;

&lt;p&gt;Building an app with React can get a bit confusing when data is being shared among components and different states lead to too much complexity and difficulty. Redux is a lightweight state management tool which can be used with any JavaScript framework or library to maintain a consistent and predictable state container. By keeping the state of an application in a single global store rather than at the component level, each individual component can access any state it needs at any time regardless of the shape of the component tree, as long as it is connected to the store via Redux.&lt;/p&gt;

&lt;p&gt;The predictable nature of Redux comes from the immutable state which never changes, as well as pure function reducers. Because reducers are functional, a commonly used middleware to handle side effect logic and asynchronous calls is &lt;a href="https://github.com/reduxjs/redux-thunk" rel="noopener noreferrer"&gt;redux-thunk&lt;/a&gt;. A Thunk allows action creators to return a function instead of an action.&lt;/p&gt;

&lt;p&gt;While I will be assuming you have a basic understanding of React and Redux, this will be a guide into a different kind of Redux middleware for handling side effects: &lt;strong&gt;Redux Sagas&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;→ &lt;em&gt;Skip to the walkthrough with sample code here&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Redux Saga?
&lt;/h3&gt;

&lt;p&gt;So long as the same action is passed to the reducer, we can be sure the store will be updated in the same way every time. Sagas, similar to normal reducers, are functions which listen for dispatched actions, perform side effects, and return their own actions back to the normal reducer. Because Sagas intercept actions with side effects and handle them, Redux reducers remain pure.&lt;/p&gt;

&lt;p&gt;Redux Saga utilizes ES6 &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*#Description" rel="noopener noreferrer"&gt;generator&lt;/a&gt; functions for this. Generators allow for synchronously written asynchronous code. A generator will automatically pause — or yield — at each asynchronous call until it completes before continuing. This paradigm allows for much simpler and more readable code by centralizing asynchronous logic for more manageable and sophisticated async flows.&lt;/p&gt;

&lt;p&gt;Saga generator functions remind me a bit of &lt;code&gt;async/await&lt;/code&gt;, with some minor changes such as &lt;code&gt;yield&lt;/code&gt; and &lt;code&gt;put()&lt;/code&gt;. Some of the differences provide powerful benefits, such as &lt;code&gt;takeLatest()&lt;/code&gt; ensuring that only the latest fetch call runs to completion despite having dispatched multiple simultaneous fetch actions. However, asynchronous calls which would normally be directly inside an action creator in a thunk will have a clear separation in Redux Sagas.&lt;/p&gt;

&lt;p&gt;Beyond code organization and attributes, testing becomes &lt;em&gt;much&lt;/em&gt; easier. A Saga merely yields a description of what to call, thus saving the need for mocking data for every test.&lt;/p&gt;

&lt;p&gt;Redux Saga becomes most useful when API or other asynchronous calls are being made with complex flows in which calls depend on the next.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; More readable code&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Good for handling complex scenarios&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Test cases become simple without necessity to mock the async behavior&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;-&lt;/code&gt; Brings in more complexity to the code&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; Additional dependency&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; A lot of concepts to learn&lt;/p&gt;

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

&lt;p&gt;→ Suited for complex async parts of the application that requires complex unit test cases&lt;/p&gt;
&lt;h3&gt;
  
  
  A quick note on Thunks:
&lt;/h3&gt;

&lt;p&gt;Given that Redux Saga seeks to orchestrate complex asynchronous operations with Redux, it is an alternative to Thunks. However, Sagas provide more functionality. Thunks work well for simple use cases, but may not be the best choice for more complicated scenarios.&lt;/p&gt;

&lt;p&gt;Thunks add a layer of indirection for more flexibility, and pass dispatch functions to the function the action creator returns. This allows the component to be agnostic towards asking for a synchronous or asynchronous action.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; Simple code to maintain&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;-&lt;/code&gt; Struggles at handling complex scenarios&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; Async behavior needs mocking for test cases&lt;/p&gt;

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

&lt;p&gt;→ Suited for small, straight forward async parts of the application&lt;/p&gt;
&lt;h3&gt;
  
  
  Generators
&lt;/h3&gt;

&lt;p&gt;Denoted with an &lt;code&gt;*&lt;/code&gt;, generators make use of the &lt;code&gt;yield&lt;/code&gt; keyword to pause the function. While &lt;code&gt;async/await&lt;/code&gt; can be transpiled into generators, the reverse cannot be done. Moreover, Sagas’ &lt;code&gt;takeLatest()&lt;/code&gt; behavior and generator function cancellation are more attributes provided by Redux Saga.&lt;/p&gt;

&lt;p&gt;When a generator function is invoked, it returns an iterator object. Each subsequent &lt;code&gt;next()&lt;/code&gt; method call will execute the generator until the next yield statement and pause.&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="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;testGenerator&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;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first yield value&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;second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second yield value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third returned value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;testGenerator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// { value: 'first yield value', done: false }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// { value: 'second yield value', done: false }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// { value: 'third returned value', done: true }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// { value: undefined, done: true }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Walkthrough:
&lt;/h3&gt;

&lt;p&gt;To guide through this concept, I will be referencing a codebase for the web app used by an open source software project I contribute to here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.accordproject.org/" rel="noopener noreferrer"&gt;Accord Project&lt;/a&gt; (AP)&lt;br&gt;
&lt;a href="https://github.com/accordproject" rel="noopener noreferrer"&gt;AP Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/accordproject/template-studio-v2" rel="noopener noreferrer"&gt;Template Studio repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project currently being built is a redesign of the &lt;em&gt;Template Studio&lt;/em&gt;. Details are mostly unimportant, suffice it to say that the part I will be going through makes an API call to gather an array of templates, and displays them in a component. This redesign will consist of many interlocking React components, all housed in one app and controlled by the Redux store. Because this began complex and will only continue to be more-so, we chose to pursue Redux Saga to handle the complexity.&lt;/p&gt;

&lt;p&gt;Unfortunately, as you may have experienced as well, there seems to be little out there as reference material. This is especially so when it comes to anything complicated.&lt;/p&gt;

&lt;p&gt;This will be a guide to following the logic behind Redux Saga in &lt;em&gt;Template Studio&lt;/em&gt; for Accord Project. Hopefully this will prove to be a useful resource for you.&lt;/p&gt;

&lt;p&gt;Setup&lt;br&gt;
Common Redux Saga methods (&lt;em&gt;called Effects&lt;/em&gt;):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;fork&lt;/code&gt;&lt;/strong&gt; → Performs a non-blocking operation on the function passed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;take&lt;/code&gt;&lt;/strong&gt; → Pauses until action received.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;race&lt;/code&gt;&lt;/strong&gt; → Runs effects simultaneously, then cancels them all once one finishes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;call&lt;/code&gt;&lt;/strong&gt; → Runs function. If it returns a promise, pauses the Saga until resolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;put&lt;/code&gt;&lt;/strong&gt; → Dispatches an action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;select&lt;/code&gt;&lt;/strong&gt; → Runs a selector function to get data from the state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;takeLatest&lt;/code&gt;&lt;/strong&gt; → Executes the operation, returns only the results of the last call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;takeEvery&lt;/code&gt;&lt;/strong&gt; → Will return results for all the calls triggered.&lt;/p&gt;



&lt;p&gt;The overall structure of the application’s flow of data will look akin to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2FsagaDiagram.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Firmerk%2Foutreach%2Fblob%2Fmaster%2Fimages%2FsagaDiagram.png%3Fraw%3Dtrue" alt="Redux Saga Flow Diagram" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To begin, we set up the main render of the app, and applying a store to the &lt;code&gt;Provider&lt;/code&gt; given by &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;react-redux&lt;/a&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MainApp&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./containers/App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./store&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&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;MainApp&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="sr"&gt;/Provider&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Store
&lt;/h4&gt;

&lt;p&gt;Pulling in the &lt;code&gt;createSagaMiddleware&lt;/code&gt; method from Redux Saga, we create &lt;code&gt;sagaMiddleware&lt;/code&gt; and run it on our rootSaga, which we will see below. Moreover, we combine all of our reducers and include this in the store upon creation.&lt;/p&gt;

&lt;p&gt;Similar to the reducers, Sagas will be registered with a rootSaga. Having the middleware use the rootSaga allows actions being dispatched to be successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;applyMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createSagaMiddleware&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;templatesReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reducers/templatesReducer&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;contractReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reducers/contractReducer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;rootSaga&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./sagas/rootSaga&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;sagaMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSagaMiddleware&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;middlewares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sagaMiddleware&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;combineReducers&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;templatesState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;templatesReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;contractState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contractReducer&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;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;rootReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;applyMiddleware&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;sagaMiddleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootSaga&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Sagas
&lt;/h4&gt;

&lt;p&gt;Sagas work in the background and &lt;code&gt;sagaMiddleware&lt;/code&gt; controls them. Being generator functions, Sagas have control over every single step of the function. We yield objects to &lt;code&gt;sagaMiddleware&lt;/code&gt; which tell it what to do with given arguments, which it will execute and resume upon completion, thus appearing to operate synchronously.&lt;/p&gt;

&lt;p&gt;Sagas are broken down to the root, watchers, and workers. All other Sagas you write are consolidated into root.&lt;/p&gt;

&lt;h5&gt;
  
  
  → Root
&lt;/h5&gt;

&lt;p&gt;All Sagas will be registered with a root Saga. Combined in an &lt;code&gt;all()&lt;/code&gt; function, they are allowed to all start at the same time each time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga/effects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;templatesSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./templatesSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;modelSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./modelSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;logicSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./logicSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sampleSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./sampleSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * saga to yield all others
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;rootSaga&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;templatesSaga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;modelSaga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;logicSaga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;sampleSaga&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;h5&gt;
  
  
  → Watcher
&lt;/h5&gt;

&lt;p&gt;Allowing the Saga to know when to start, this generator function watches for actions (&lt;em&gt;similar to reducers&lt;/em&gt;) and calls worker Sagas to do an API call. This function is on &lt;code&gt;Line 62&lt;/code&gt; below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TemplateLibrary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@accordproject/cicero-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ciceroVersion&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@accordproject/cicero-core/package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;takeLatest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;takeEvery&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga/effects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../actions/templatesActions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;selectors&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../selectors/templatesSelectors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * worker saga
 * saga to populate store with templates
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;pushTemplatesToStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;templateLibrary&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;TemplateLibrary&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;templateIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;templateLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTemplateIndex&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;latestVersion&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="nx"&gt;ciceroVersion&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;templateIndexArray&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="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;templateIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTemplatesSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;templateIndexArray&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTemplatesError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * worker saga
 * saga which puts a mock template onto the array
 * of templates in the store
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;addNewTemplateToStore&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;newTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Temporary New Template&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&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 mock data to showcase an action to add a new template.&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="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNewTemplateSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTemplate&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * worker saga
 * saga which checks if template is in the store
 * and loads the template if it is not
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;addTemplateObjectToStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;templateObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templateObjects&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;templateObjects&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;templateObjects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;templateObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadTemplateObjectSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;templateObj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadTemplateObjectError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * watcher saga
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;templatesSaga&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nf"&gt;takeLatest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_AP_TEMPLATES&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pushTemplatesToStore&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;takeLatest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_NEW_TEMPLATE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addNewTemplateToStore&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nf"&gt;takeEvery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addTemplateObjectToStore&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;Similar to &lt;code&gt;takeLatest()&lt;/code&gt;, &lt;code&gt;takeEvery()&lt;/code&gt; allows multiple instances of Sagas to run simultaneously. These are both built on &lt;code&gt;take()&lt;/code&gt;, which is synchronous.&lt;/p&gt;

&lt;h5&gt;
  
  
  → Worker
&lt;/h5&gt;

&lt;p&gt;This Saga (&lt;code&gt;Lines 14&lt;/code&gt;, &lt;code&gt;31&lt;/code&gt;, and &lt;code&gt;46&lt;/code&gt; above) will perform a side effect. Once data loads, the &lt;code&gt;put()&lt;/code&gt; method is used to dispatch another action. This does not directly dispatch, but rather creates an effect description that tells Redux Saga to dispatch it. Because &lt;code&gt;put()&lt;/code&gt; expects an action for an argument, it serves as an action creator. We modularized these actions out, though, as you will see below.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reducer
&lt;/h4&gt;

&lt;p&gt;Similar to actions, reducers are the same for Redux Saga. This is simply a function that takes state and action as arguments, and returns the next state of the app. While an action only describes what happened, a reducer describes &lt;em&gt;how the application’s state changes&lt;/em&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;const&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;templatesAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;templateObjs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;error&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET_AP_TEMPLATES_SUCEEDED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_AP_TEMPLATES_SUCEEDED&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;AP_TEMPLATES_ERROR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AP_TEMPLATES_ERROR&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;ADD_NEW_TEMPLATE_SUCCEEDED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_NEW_TEMPLATE_SUCCEEDED&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;LOAD_TEMPLATE_OBJECT_SUCCEEDED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT_SUCCEEDED&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;LOAD_TEMPLATE_OBJECT_ERROR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT_ERROR&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;reducer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;GET_AP_TEMPLATES_SUCEEDED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;templatesAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templates&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;ADD_NEW_TEMPLATE_SUCCEEDED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;templatesAP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templatesAP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;AP_TEMPLATES_ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="na"&gt;LOAD_TEMPLATE_OBJECT_SUCCEEDED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;templateObjs&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templateObjs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templateObj&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;case&lt;/span&gt; &lt;span class="na"&gt;LOAD_TEMPLATE_OBJECT_ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Component
&lt;/h4&gt;

&lt;p&gt;Moving into the component, we have a straightforward approach to setting up state and dispatching to result in cleaner 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prop-types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styled-components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TemplateLibrary&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@accordproject/cicero-ui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getTemplatesAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;addNewTemplateAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../actions/templatesActions&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;TLWrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&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;mockAddToCont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;addToCont: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&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;mockImport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;import&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;upload&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LibraryComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PureComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchAPTemplates&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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;TLWrapper&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;TemplateLibrary&lt;/span&gt;
          &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mockUpload&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mockImport&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;addTemp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addNewTemplate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;addToCont&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mockAddToCont&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/TLWrapper&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;LibraryComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;addNewTemplate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fetchAPTemplates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&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;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templatesState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templatesAP&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;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;fetchAPTemplates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getTemplatesAction&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="na"&gt;addNewTemplate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;addNewTemplateAction&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="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;LibraryComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Action Creator
&lt;/h4&gt;

&lt;p&gt;Dispatched to the store for handling, actions are objects containing a description of an event. Because actions are made by action creator functions, the one dispatching the action does not need to know the exact structure.&lt;/p&gt;

&lt;p&gt;With Sagas, actions are slightly different. Three actions happen for each API call. Beginning the action, successful response, and error response. While this pattern does not change, the location of each call may.&lt;/p&gt;

&lt;p&gt;Beginning an action starts within the component, which may add necessary info for making the call. Worker Sagas will be dispatching success and error actions.&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTemplatesAction&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_AP_TEMPLATES&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTemplatesSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;templateIndexArray&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_AP_TEMPLATES_SUCEEDED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;templateIndexArray&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTemplatesError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AP_TEMPLATES_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;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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addNewTemplateAction&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_NEW_TEMPLATE&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addNewTemplateSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_NEW_TEMPLATE_SUCCEEDED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;template&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadTemplateObjectAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadTemplateObjectSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;templateObj&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT_SUCCEEDED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;templateObj&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadTemplateObjectError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LOAD_TEMPLATE_OBJECT_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;error&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;
  
  
  Recap
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;(&lt;code&gt;TemplateLibrary.js&lt;/code&gt;)
When the &lt;code&gt;LibraryComponent&lt;/code&gt; mounts, an action (&lt;code&gt;getTemplatesAction&lt;/code&gt;) is dispatched&lt;/li&gt;
&lt;li&gt;(&lt;code&gt;templatesActions.js&lt;/code&gt;)
As we can see, &lt;code&gt;getTemplatesAction&lt;/code&gt; dispatches an object with a type: &lt;code&gt;‘GET_AP_TEMPLATES’&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;(&lt;code&gt;templatesSaga.js&lt;/code&gt;)
The watcher will pick up on the action of type &lt;code&gt;‘GET_AP_TEMPLATES’&lt;/code&gt; and call &lt;code&gt;pushTemplatesToStore&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;(&lt;code&gt;templatesSaga.js&lt;/code&gt;)
When pushTemplatesToStore is called, a few things happen. We yield an API call made by the &lt;code&gt;TemplateLibrary&lt;/code&gt; imported from &lt;code&gt;@accordproject/cicero-core&lt;/code&gt; and put it in an array. From there, &lt;code&gt;getTemplatesSuccess&lt;/code&gt; is called with the array of templates as an argument.&lt;/li&gt;
&lt;li&gt;(&lt;code&gt;templatesReducer.js&lt;/code&gt;)
This action (&lt;code&gt;GET_AP_TEMPLATES_SUCEEDED&lt;/code&gt;) ends up in the reducer, updating the state with the templates array which was attached to the action.&lt;/li&gt;
&lt;li&gt;(&lt;code&gt;TemplateLibrary.js&lt;/code&gt;)
Because this component is subscribed to the store and has props *prop*agated to it, the templates array is now applied to this component through props.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;p&gt;Approaching testing for Redux Saga may be intimidating. A general rule for efficiency in Redux Sagas is to ensure Sagas are doing as little as possible and to move any complex logic out into a separate regular function. A couple approaches I would recommend pursuing:&lt;/p&gt;

&lt;h4&gt;
  
  
  Unit Tests
&lt;/h4&gt;

&lt;p&gt;This approach steps through yield effects individually with the &lt;code&gt;next()&lt;/code&gt; method. A test may inspect the yielded effect and compare it to an expected effect with &lt;code&gt;next().value&lt;/code&gt;. While this is straightforward, it leads to brittle tests. This is due to the tests being coupled so tightly with the implementation and order of effects. Refactoring code will likely break tests.&lt;/p&gt;

&lt;p&gt;A helper function called &lt;code&gt;recordSaga&lt;/code&gt; is used to start a given saga outside the middleware with an action. The options object (&lt;code&gt;dispatch&lt;/code&gt; and &lt;code&gt;getState&lt;/code&gt;)is used to define behavior of side effects. &lt;code&gt;dispatch&lt;/code&gt; fulfills put effects, and &lt;code&gt;dispatched&lt;/code&gt; accumulates all the actions in a list and returns it after the Saga finishes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;runSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * saga to test independently
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recordSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;saga&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;initialAction&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPromise&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;dispatched&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;Utilizing &lt;code&gt;recordSaga&lt;/code&gt; allows us to view the type of the dispatched action in a given test case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TemplateLibrary&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@accordproject/cicero-core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addNewTemplateToStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pushTemplatesToStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../templatesSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;recordSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../utilities/test/sagaTest&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;mockedTemplateIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ciceroVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^0.12.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&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 clause allows the receiver of goods to inspect them for a given time period after delivery.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;acceptance-of-delivery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ap://acceptance-of-delivery@0.11.0#311de48109cce10e6b2e33ef183ccce121886d0b76754d649d5054d1084f93cd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://templates.accordproject.org/archives/acceptance-of-delivery@0.11.0.cta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.11.0&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;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@accordproject/cicero-core&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;TemplateLibrary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nf"&gt;beforeEach&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;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resetModules&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pushTemplatesToStore&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should dispatch the action getTemplatesSuccess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;TemplateLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockImplementation&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="na"&gt;getTemplateIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mockedTemplateIndex&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;dispatched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;recordSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pushTemplatesToStore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatched&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET_AP_TEMPLATES_SUCEEDED&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should dispatch an error if templates fetch fails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;TemplateLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockImplementation&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="na"&gt;getTemplateIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unable to recieve templates&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;}));&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;recordSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pushTemplatesToStore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatched&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AP_TEMPLATES_ERROR&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;addNewTemplateToStore&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should dispatch the action addNewTemplateSuccess&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;dispatched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;recordSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addNewTemplateToStore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatched&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ADD_NEW_TEMPLATE_SUCCEEDED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Integration Tests
&lt;/h4&gt;

&lt;p&gt;This approach tests the effects you’re interested in. In this, you will execute the Saga until the end, mocking effects along the way. Because this is not run in isolation, results are more secure. Now refactoring should not break the tests nearly as easily. To make this process easier, we utilize the module by &lt;a href="https://medium.com/u/be7a06b10aa3" rel="noopener noreferrer"&gt;Jeremy Fairbank&lt;/a&gt; - &lt;a href="https://redux-saga-test-plan.jeremyfairbank.com/" rel="noopener noreferrer"&gt;redux-saga-test-plan&lt;/a&gt; , which helps to make assertions in the effects generated by Sagas.&lt;/p&gt;

&lt;p&gt;This module contains &lt;code&gt;expectSaga&lt;/code&gt; which returns an API for asserting that a Saga yields certain effects. It takes the generator function as an argument, along with additional arguments to pass to the generator. While &lt;code&gt;expectSaga&lt;/code&gt; runs on &lt;code&gt;runSaga&lt;/code&gt;, which we used in &lt;code&gt;sagaTest&lt;/code&gt;, it provides a bit easier usage. This also means that &lt;code&gt;expectSaga&lt;/code&gt; is asynchronous.&lt;/p&gt;

&lt;p&gt;After calling &lt;code&gt;expectSaga&lt;/code&gt; with assertions, start the Saga with &lt;code&gt;run()&lt;/code&gt;. This returns a &lt;code&gt;Promise&lt;/code&gt; which can then be used with a testing framework. We use Jest. If all assertions pass, the &lt;code&gt;Promise&lt;/code&gt; will resolve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga/effects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expectSaga&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redux-saga-test-plan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ModelManager&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;composer-concerto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;updateModelManagerSuccess&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../actions/modelActions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;updateModelFileOnStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validateModelFiles&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../modelSaga&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;validateModelFiles&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should complete successful update to model manager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;modelFiles&lt;/span&gt; &lt;span class="o"&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;test.cto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
                /**
                 * This is a comment
                 */

                namespace test

                asset Vehicle identified by vin {
                  o String vin default="unknown"
                }

                // this is another comment
                participant Person identified by ssn {
                  o String name
                  o String ssn
                  o DateTime dob
                  --&amp;gt; Vehicle vehicle
                }`&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;modelState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;modelFiles&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;const&lt;/span&gt; &lt;span class="nx"&gt;modelManager&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;ModelManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelFiles&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileName&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;modelManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addModelFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelFiles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;modelManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateExternalModels&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;modelManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateModelFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;expectSaga&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validateModelFiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;updateModelManagerSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelManager&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&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;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Redux Saga is amazing. They provide a very clean way of performing asynchronous calls in Redux, and encourages clear, modularized code. While it is possible to accomplish the same feat without it, this will prove quite difficult and I feel it is worth the time to learn.&lt;/p&gt;

&lt;p&gt;Feel free to contact me with any questions or feedback.&lt;/p&gt;

</description>
      <category>redux</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Git Workflow Etiquette</title>
      <dc:creator>Jolene Langlinais</dc:creator>
      <pubDate>Thu, 08 Aug 2019 22:26:05 +0000</pubDate>
      <link>https://forem.com/jolanglinais/git-workflow-etiquette-1kgj</link>
      <guid>https://forem.com/jolanglinais/git-workflow-etiquette-1kgj</guid>
      <description>&lt;h2&gt;
  
  
  Repository Organization for Clean Codebases
&lt;/h2&gt;

&lt;p&gt;Version control with git provides for powerful collaboration, whether it be a tight-knit tech team or a distributed network in an open source format. Still, proper care must be taken. &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; is used widely within the software development field and can manage a constantly evolving codebase. Most of its usefulness comes from the ability to branch off new work from an existing project in order to work on it in isolation until ready to integrate back into the project.&lt;/p&gt;

&lt;p&gt;Good quality software consists of, among other things, code which is robust, resilient, secure, and performant. These attributes are achievable by maintaining a foundation of good quality code and a solid history of documentation. Anyone should be able to join the process and easily figure out and track the status of the project. This is where git and &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; come in.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Skip to the following&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;→ Branch vs. Fork&lt;br&gt;
→ Rebase vs. Merge&lt;br&gt;
→ CLI&lt;br&gt;
→ Commit (Messages)&lt;br&gt;
→ Pull Requests (and Reviews)&lt;br&gt;
→ GitHub Issues&lt;br&gt;
→ Open Source&lt;/p&gt;
&lt;h4&gt;
  
  
  Approach
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvfvvmu7kmqvepby5mch2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvfvvmu7kmqvepby5mch2.png" alt="Accord Project Log" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My experience as a contributor to the &lt;a href="https://www.accordproject.org/" rel="noopener noreferrer"&gt;Accord Project&lt;/a&gt;, an open source project for smart legal contracts, has led me to adopt and implement a standard of git workflow and etiquette which I find thorough and effective.&lt;/p&gt;

&lt;p&gt;I will be sharing this as both a useful reference for others, as well as a historical reference for myself in the future. As is readily apparent by now, I am utilizing both git and GitHub. For perspective, you can reference GitHub’s official workflow proposal (&lt;a href="https://guides.github.com/introduction/flow/" rel="noopener noreferrer"&gt;GitHub flow&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The majority of my work at the Accord Project is in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;, with some domain specific language mixed in, but the principles displayed here should apply to any language.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Branch + Fork:
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Branching
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; All project work is centralized&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Ease of collaboration&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Single remote to handle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;—&lt;/code&gt;  Deprecated branches may clutter easily&lt;/p&gt;
&lt;h4&gt;
  
  
  Forking
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; Increased separation between user branches&lt;br&gt;
&lt;code&gt;+&lt;/code&gt; Primary repository cleanliness&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;—&lt;/code&gt; Difficulty to track branches&lt;br&gt;
&lt;code&gt;—&lt;/code&gt; Collaboration requires extra steps&lt;br&gt;
&lt;code&gt;—&lt;/code&gt; Accessibility is lower for less experienced git users&lt;/p&gt;

&lt;p&gt;While there are benefits to both of these approaches, my general rule consists of forking in an open source project and branching in a smaller or insular team. There is more incentive for keeping the main repository clean and tidy in open source, and less chance of quick-and-dirty collaboration on a branch. Conversely, a tech team would benefit from a centralized repository with trackable branches. Either way will necessitate strict organization.&lt;/p&gt;

&lt;p&gt;As an open source project, the Accord Project follows the fork workflow model. Still, the &lt;code&gt;main&lt;/code&gt; branches should be kept in sync (&lt;a href="https://help.github.com/en/articles/syncing-a-fork" rel="noopener noreferrer"&gt;guide for syncing&lt;/a&gt;), and every feature, bug fix, release, or code change should occur in a different branch. This will be discussed more in the next section.&lt;/p&gt;

&lt;p&gt;Naming a new branch will be one of the first steps in keeping a consistent tracking system of Issues, pull requests, and git history. The important factor here is consistency.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;name/issue-tracker/short-description&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;: Anything from initials to full name to GitHub username&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;issue-tracker&lt;/code&gt;&lt;/strong&gt;: Reference the issue from GitHub or some other agile user stories source&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;short-description&lt;/code&gt;&lt;/strong&gt;: One to three words describing the main goal of this branch, separated by hyphens&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;irmerk/i7/new-feature&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the case of collaborating on a single feature, maintain a single, &lt;code&gt;main&lt;/code&gt; branch for the feature and individual branches from it. This can follow the previous naming convention:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main/i14/routing-service // team branch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;irmerk/i14/routing-service // my branch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;someone/i14/routing-service // someone else's branch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Personal branches can be merged into the &lt;code&gt;main&lt;/code&gt; team branch, which will then be merged with the overall &lt;code&gt;main&lt;/code&gt; through a pull request. Delete branches after they are merged.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Rebase + Squash
&lt;/h3&gt;

&lt;p&gt;Common practice for teams is to squash or condense long commit message chains into one or a few commits before merging into &lt;code&gt;main&lt;/code&gt;. This is useful when, like me, someone commits frequently and thus would clutter a git log. Squashing serves to maintain a readable git log.&lt;/p&gt;

&lt;p&gt;Prior to merging a feature branch into the main (&lt;code&gt;main&lt;/code&gt;) branch, it should be rebased from the up-to-date &lt;code&gt;main&lt;/code&gt;. A pull request, discussed later, will be where all the commits of this branch are squashed down to a single buildable commit and merged into &lt;code&gt;main&lt;/code&gt;. Rebasing essentially ports a branch (&lt;code&gt;main&lt;/code&gt;) into your current branch by applying all of your commits on top of that branch (&lt;code&gt;main&lt;/code&gt;), then replacing your branch with the revised version. This catches you up to a branch (&lt;code&gt;main&lt;/code&gt;) by rewriting git history in your local git.&lt;/p&gt;

&lt;p&gt;Think of it as moving your branch to the tip of &lt;code&gt;main&lt;/code&gt; instead of having branched off from an earlier version of &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of needing to heavily investigate individual commits from a branch, each merge commit to &lt;code&gt;main&lt;/code&gt; should contain all the code for a feature or bug fix. This allows for a much easier investigation process.&lt;/p&gt;

&lt;p&gt;While squashing prior to rebasing reduces conflicts due to fewer steps of conflict resolution, it literally changes the history of the repository as documented on GitHub for everyone, and thus is not the most accurate representation. Rebasing before squashing retains the git log tidiness and you don’t change history prior to documenting it on GitHub.&lt;/p&gt;
&lt;h4&gt;
  
  
  Interactive Rebase
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git rebase -i&lt;/code&gt; is super useful in several circumstances, such as needing to quickly remove a commit. If your team has a policy in which any feature commit must also contain tests for that feature, squashing several commits into one can be helpful. This would involve &lt;code&gt;git rebase -i HEAD~n&lt;/code&gt; and replace &lt;code&gt;n&lt;/code&gt; with the number of commits — replace &lt;code&gt;pick&lt;/code&gt; on those commits’ lines to &lt;code&gt;squash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If your project, like the Accord Project, requires a &lt;a href="https://developercertificate.org/" rel="noopener noreferrer"&gt;Developer Certificate of Origin&lt;/a&gt; sign-off, you may find yourself needing to rapidly change the messages on a series of commits. Similarly to before, change &lt;code&gt;pick&lt;/code&gt; to &lt;code&gt;edit&lt;/code&gt; on the commits needing to change and simply &lt;code&gt;git commit --amend -s&lt;/code&gt; and &lt;code&gt;git rebase --continue&lt;/code&gt; for each commit. &lt;code&gt;git push -f&lt;/code&gt; into the branch for the pull request. &lt;strong&gt;Caution&lt;/strong&gt;: Force pushing can have dire consequences if not used properly, consult others if unsure how to use this.&lt;/p&gt;

&lt;p&gt;Generally, if you do not have large, confusing conflicts, &lt;code&gt;-i&lt;/code&gt; (interactive rebase) will be overkill.&lt;/p&gt;
&lt;h4&gt;
  
  
  Rewriting History
&lt;/h4&gt;

&lt;p&gt;While rewriting history with &lt;code&gt;git rebase&lt;/code&gt; is extremely useful in some cases, caution should still be taken. Make sure to not interrupt other people’s history and commits on accident. &lt;strong&gt;Caution&lt;/strong&gt;: Avoid force pushing to a remote branch other people are working on.&lt;/p&gt;
&lt;h4&gt;
  
  
  Fear
&lt;/h4&gt;

&lt;p&gt;I still fear &lt;code&gt;rebase&lt;/code&gt; and &lt;code&gt;squash&lt;/code&gt;. Merge conflicts can be more frequent and seem more difficult. I’ve had experiences of losing work due to incorrectly rebasing.&lt;/p&gt;

&lt;p&gt;However, if you frequently commit ongoing work, rebasing complications should be infrequent. Fixing conflicts and &lt;code&gt;git rebase --continue&lt;/code&gt; can feel intimidating at first, but continue working with it. A merge commit will be made with these conflicts, but that is important history on how a conflict was resolved. You can always try again if you feel it is going poorly with &lt;code&gt;git rebase --abort&lt;/code&gt; and try again — this reverts too before the &lt;code&gt;rebase&lt;/code&gt; attempt.&lt;/p&gt;
&lt;h4&gt;
  
  
  Flow
&lt;/h4&gt;

&lt;p&gt;My recommendation for a general workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure you are currently in &lt;code&gt;main&lt;/code&gt;
→ If working in a &lt;code&gt;fork&lt;/code&gt;, fetch:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git fetch &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--prune&lt;/span&gt;
git merge &lt;span class="nt"&gt;--ff-only&lt;/span&gt; upstream/main
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;→ If working in a &lt;code&gt;branch&lt;/code&gt;, pull:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git pull origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a new branch for your feature or bug fix
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; branchName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Make changes with as many commits as necessary. The final commit should build and pass tests.&lt;/li&gt;
&lt;li&gt;Make sure your branch sits on top of &lt;code&gt;main&lt;/code&gt; (as opposed to branch off a branch). This ensures the reviewer will need only minimal effort to integrate your work by fast-fowarding &lt;code&gt;main&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase upstream/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If you have previously pushed your code to a remote branch, you will need to force push. If not, omit the -f tag.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin branchName &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open a pull request in GitHub from this forked branch. Once this has been merged to &lt;code&gt;main&lt;/code&gt;, remember to clear out your branch locally
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-D&lt;/span&gt; branchName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Merge
&lt;/h4&gt;

&lt;p&gt;As a non-destructive operation, merging can be nice. However, if the &lt;code&gt;main&lt;/code&gt; you are working on is quite active, the git log can be polluted quickly by the extra commit created by a merge operation.&lt;/p&gt;

&lt;p&gt;While many developers are uncomfortable with rebasing and resort to merge &lt;code&gt;main&lt;/code&gt; on top of their changes, merging is not always the best option. If merging locally instead of rebasing, at the very least squash a pull request to merge into &lt;code&gt;main&lt;/code&gt; on GitHub. This allows for greater control of the commit messages in &lt;code&gt;main&lt;/code&gt; for the git log.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; CLI
&lt;/h3&gt;

&lt;p&gt;The Command Line Interface (CLI) is a place you can run &lt;em&gt;all&lt;/em&gt; git commands. Git graphical user interfaces (GUI) such as &lt;a href="https://www.gitkraken.com/" rel="noopener noreferrer"&gt;GitKraken&lt;/a&gt; and &lt;a href="https://www.git-tower.com/" rel="noopener noreferrer"&gt;Tower&lt;/a&gt; are great. I opt to not use them due to them being priced as well as the vast majority of solutions found online involving git are for CLI.&lt;/p&gt;

&lt;p&gt;Moreover, knowing the CLI method of git allows you to easily navigate a GUI, but the reverse is not necessarily the case. Learning to interact with git and GitHub via the CLI will be a great use of your time, especially if you work with open source projects.&lt;/p&gt;

&lt;h4&gt;
  
  
  Diff
&lt;/h4&gt;

&lt;p&gt;A good habit to adopt is utilizing &lt;code&gt;git diff&lt;/code&gt; prior to committing anything. This allows you to ensure the code being committed is what you expect, all debugging statements are removed, and no junk is included.&lt;/p&gt;

&lt;h4&gt;
  
  
  Log
&lt;/h4&gt;

&lt;p&gt;Logs reveal a history of everything that happens in a repository. This tool has many options for displaying commit history in specific ways. A full log contains a commit hash, author, date, and message. My preferred way of logging builds an ASCII graph representing the branch structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--decorate&lt;/span&gt; &lt;span class="nt"&gt;--pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;oneline &lt;span class="nt"&gt;--abbrev-commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Blame
&lt;/h4&gt;

&lt;p&gt;A method for inspecting who changed what and when in files is &lt;code&gt;git blame&lt;/code&gt;. If you code in &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt;, I strongly recommend looking into &lt;a href="https://gitlens.amod.io/" rel="noopener noreferrer"&gt;GitLens&lt;/a&gt;, which makes this inspection inline and extremely efficient.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Commits
&lt;/h3&gt;

&lt;p&gt;A single logical change should be captured in a commit. More than one logical changes in a commit — an instance in which you may find yourself writing &lt;em&gt;“and”&lt;/em&gt; in a commit message — is a good indicator of needing to split into two separate commits.&lt;/p&gt;

&lt;p&gt;Commit often — do not let yourself get too far without committing. Small, incremental and self contained commits are easier to follow or revert in the future.&lt;/p&gt;

&lt;p&gt;While ordering commits logically would be ideal, I recommend committing in the order in which you are working — this is a chronological history of what you did.&lt;/p&gt;

&lt;h4&gt;
  
  
  Messages
&lt;/h4&gt;

&lt;p&gt;Take a moment for this process — a commit message should not be rushed. The description of a commit should be well documented, and thus will prove invaluable to whoever reads this in the future in attempt to understand why a change was made — even if they have little to no context. This accessibility is a vital goal for a thorough git history and workflow.&lt;/p&gt;

&lt;p&gt;Include external information references such as Issues or pull requests. Anything that will be helpful to others or your future self should be reasoned out now. The long term success of a project relies on the maintainability of the code and log. A hassle at first pays off as a healthy habit.&lt;/p&gt;

&lt;p&gt;Use the terminal, not the editor, when writing a commit message. Committing from the terminal encourages a mindset of describing a change in an incremental way, as well as keeping commits atomic — commits should not need a paragraph of explanation. This will assist you in creating a pull request message, where an overall change should be captured. More on this later.&lt;/p&gt;

&lt;p&gt;Concise and consistent commit messages should be captured by always including the &lt;code&gt;-m &amp;lt;msg&amp;gt;&lt;/code&gt; flag to a &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Formatting
&lt;/h4&gt;

&lt;p&gt;A properly formed &lt;code&gt;git commit&lt;/code&gt; subject line should always be able to complete the following sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If applied, this commit will &lt;strong&gt;&lt;code&gt;your subject line here&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;type(scope): subject — footer&lt;/code&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feat&lt;/code&gt;— A new feature&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fix&lt;/code&gt;— A bug fix&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs&lt;/code&gt;— Changes to only documentation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;style&lt;/code&gt;— Changes to formatting (missing semi colons, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refactor&lt;/code&gt;— A code change that neither fixes a bug nor adds a feature&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;— Adding missing or correcting existing tests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chore&lt;/code&gt;— Change to build process or auxiliary tools, or maintenance&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Focal point of new code or best description for where changes can be found.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Imperative description of changes, kept under 50 characters (not capitalized and no period)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;GitHub Issue reference ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;utilities&lt;span class="o"&gt;)&lt;/span&gt;: include optional state &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;test &lt;/span&gt;utility - I22
    // implement a feature &lt;span class="k"&gt;in &lt;/span&gt;src/utilities/test/sagaTest.js
&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;sagas&lt;span class="o"&gt;)&lt;/span&gt;: initiate &lt;span class="nb"&gt;test &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;failed templates fetch - I22
    // tests run &lt;span class="k"&gt;in &lt;/span&gt;and of src/sagas/&lt;span class="k"&gt;*&lt;/span&gt;
chore&lt;span class="o"&gt;(&lt;/span&gt;package&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="nb"&gt;install &lt;/span&gt;saga testing library - I22
    // edits to dependencies &lt;span class="k"&gt;in &lt;/span&gt;package.json
docs&lt;span class="o"&gt;(&lt;/span&gt;README&lt;span class="o"&gt;)&lt;/span&gt;: add netlify badge and update - I27
    // alter documentation &lt;span class="k"&gt;in &lt;/span&gt;the readme file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Pull Requests
&lt;/h3&gt;

&lt;p&gt;A pull request (PR) is one of the best ways to share information. While an Issue describes what may be wrong or a feature, a PR provides a medium for what changes are actually occurring to the codebase. Moreover, it is excellent for peer reviews and accountability, as it encourages quality commits. When done well, the commits that construct a PR tell the whole story to those who review the code or examine it in the future.&lt;/p&gt;

&lt;p&gt;PRs should consist of a complete addition to the code which contains value. Because the commits inside follow a pattern, the title should be an extension or summary of all the commits inside. Thus, earlier when I spoke of squashing, a git log will retain the pattern of each commit even after it is tidied up. To emphasize, &lt;strong&gt;a PR title should follow commit message formatting described above&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As a GitHub workflow tool, the innards of a PR are less important than the title maintaining the consistency and efficiency of formatting. This allows git logs to remain efficient with or without GitHub.&lt;/p&gt;

&lt;p&gt;Similar to commits, PRs should be small. A PR which attempts to do multiple things (find yourself writing &lt;em&gt;“and”&lt;/em&gt; in the title?) should be split up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cleanup
&lt;/h4&gt;

&lt;p&gt;As discussed previously, rebasing prior to creating a PR is a good tidying habit. Take a moment to merge any extra commits created along the way, or reword commits for clarity. Every commit in a PR should be directly working towards the goal of the title of the PR, or even the related GitHub Issue.&lt;/p&gt;

&lt;h4&gt;
  
  
  Formatting
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--- Provide a formatted commit message describing this PR in the Title above --&amp;gt;&lt;/span&gt;
&lt;span class="gh"&gt;# Closes #&amp;lt;CORRESPONDING ISSUE NUMBER&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Provide an overall summary of the pull request --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;### Changes&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- More detailed and granular description of changes --&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- These should likely be gathered from commit message summaries --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;ONE&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;TWO&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;### Flags&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Provide context or concerns a reviewer should be aware of --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;ONE&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;TWO&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;### Screenshots or Video&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Provide an easily accessible demonstration of the changes, if applicable --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;### Related Issues&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Issue #&lt;span class="nt"&gt;&amp;lt;NUMBER&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Pull Request #&lt;span class="nt"&gt;&amp;lt;NUMBER&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;### Author Checklist&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt; ] Ensure you provide a [DCO sign-off&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://github.com/probot/dco#how-it-works&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; for your commits using the &lt;span class="sb"&gt;`--signoff`&lt;/span&gt; option of git commit.
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Vital features and changes captured in unit and/or integration tests
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Extend the documentation, if necessary
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Merging to &lt;span class="sb"&gt;`main`&lt;/span&gt; from &lt;span class="sb"&gt;`fork:branchname`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Manual accessibility test performed
&lt;span class="p"&gt;    -&lt;/span&gt; [ ] Keyboard-only access, including forms
&lt;span class="p"&gt;    -&lt;/span&gt; [ ] Contrast at least WCAG Level A
&lt;span class="p"&gt;    -&lt;/span&gt; [ ] Appropriate labels, alt text, and instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub PRs are in Markdown&lt;br&gt;
Keep in mind: What does this change do to address the issue and what side effects may it have? Why was it necessary? Try to preempt a reviewer needing to ask questions, be thorough in your information.&lt;/p&gt;
&lt;h4&gt;
  
  
  Drafts
&lt;/h4&gt;

&lt;p&gt;GitHub offers a useful option for a PR which is not ready to be reviewed quite yet. If you want to have a source of truth in a PR for others to interact with prior to actual review, or even just to ensure the code is saved on GitHub and not only on your local machine, open a draft pull request.&lt;/p&gt;
&lt;h4&gt;
  
  
  Reviews
&lt;/h4&gt;

&lt;p&gt;Setting a standard for PR reviews is important, and being thorough equally so. A reviewer is a guardian of the git history and code quality. This cannot be stressed enough. What seems obvious now will surely not be so in months’ or years’ time. Do not feel bad for requesting changes or having changes requested of you. It is better to have pristine code merged into &lt;code&gt;main&lt;/code&gt; than to rush through out of desire to be done with a feature.&lt;/p&gt;

&lt;p&gt;Strike a balance between the flow of getting PRs through and not holding up further edits or production, and maintaining quality. Every reviewer should make a judgment on whether an issue is sufficient enough to block a PR. However, anyone who contributes to the PR should not be reviewing what is merged into &lt;code&gt;main&lt;/code&gt;. Keep a healthy separation between these roles. Generally, it is faster for the PR author to fix the code than for a reviewer to be involved.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt; GitHub
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Issues
&lt;/h4&gt;

&lt;p&gt;Very easy to maintain, Issues should be used liberally. Any question, idea, or bug — duplicate or not — should be reason enough to open an Issue. These are the foundation of conversations in projects, so insert points of view and establish a concrete record of discussions which can be searched and linked.&lt;/p&gt;

&lt;p&gt;Speaking of which, search through a project before opening an Issue. While duplicates can be easily closed, this is a courtesy to other contributors. Also, be thorough and provide as much context as possible. Maybe even take a moment to read the project’s documentation on contributing, they may have guidelines on formatting an Issue.&lt;/p&gt;

&lt;p&gt;Example feature request formatting of an Issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--- Provide a general summary of the feature in the Title above --&amp;gt;&lt;/span&gt;
&lt;span class="gh"&gt;# Feature Request 🛍️&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Provide an expanded summary of the feature --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Use Case&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Tell us what feature we should support and what should happen --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Possible Solution&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Not obligatory, but suggest an implementation --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Context&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- How has this issue affected you? What are you trying to accomplish? --&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Providing context helps us come up with a solution that is most useful in the real world --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Detailed Description&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- Provide a detailed description of the change or addition you are proposing --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Noise
&lt;/h4&gt;

&lt;p&gt;Stay mindful of what you are presenting for others to read. Is it worth their time? Avoid posting short, rushed answers or responses. Take the time to be worthwhile to yourself and others in your contributions. Provide as much context as possible while still being helpful. Too little and too much context are both quite awful.&lt;/p&gt;

&lt;p&gt;If a significant amount of time has passed, send a gentle bump to reviewers. It can be easy to forget about an active PR.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Open Source
&lt;/h4&gt;

&lt;p&gt;I recommend this &lt;a href="https://opensource.guide/how-to-contribute/" rel="noopener noreferrer"&gt;guide&lt;/a&gt; for contributing to open source. GitHub provides great functionalities which should be utilized for the best possible experience of contributing developers. Issues can be tagged for ease of navigation, protections can be enforced to prevent direct commits to &lt;code&gt;main&lt;/code&gt;, and multiple reviewers can be required.&lt;/p&gt;

&lt;p&gt;This guide is aimed at providing a framework which fosters a healthy, collaborative atmosphere. All of this can be applied and tweaked for any open source or proprietary tech team environment.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Contribute the work you would like to see. Politeness, respect, thoroughness, and efficiency are all things we appreciate, so develop and maintain good habits with git and collaborations will be the best they can be.&lt;/p&gt;

&lt;p&gt;Perception is important in open source, and how others view the git log can make a big difference. Take time to care for the log with efficient commits and git etiquette. This is also true for a company and a new hire.&lt;/p&gt;

&lt;p&gt;Feel free to contact me with any questions or feedback.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
