<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: David</title>
    <description>The latest articles on DEV Community by David (@daveturissini).</description>
    <link>https://dev.to/daveturissini</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%2F194893%2F04027f3f-2081-44df-abac-445eca539d58.jpg</url>
      <title>DEV Community: David</title>
      <link>https://dev.to/daveturissini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daveturissini"/>
    <language>en</language>
    <item>
      <title>Build Your Own AI Code Review Workflow in 5 Minutes with Github Actions</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 27 May 2025 03:55:12 +0000</pubDate>
      <link>https://dev.to/daveturissini/build-your-own-ai-code-review-agent-in-5-minutes-with-github-actions-2kcg</link>
      <guid>https://dev.to/daveturissini/build-your-own-ai-code-review-agent-in-5-minutes-with-github-actions-2kcg</guid>
      <description>&lt;p&gt;Curious how well a large language model (LLM) can review your code? In this post, I'll show you how to set up a custom AI-powered code review tool in just 5 minutes using GitHub Actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;This article assumes some level of familarity with Javascript and Github Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;We'll build a GitHub Actions workflow that passes a pull request's changeset to ChatGPT. We'll prompt ChatGPT to review the changes and provide feedback. We'll then take its response and post it back to the original PR so that the PR author can see the feeback.&lt;/p&gt;

&lt;p&gt;This is a very simple and straight forward way to see how simple it is to integrate LLMs into your workflow &lt;em&gt;right now&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Get an API Token for your LLM
&lt;/h2&gt;

&lt;p&gt;First, you'll need an API token to programmatically access ChatGPT. You'll also need permission to add secrets to your GitHub repository or organization.&lt;/p&gt;

&lt;p&gt;Once you have your API token, add it to your repo or org secrets. We will reference the secret in our Github Actions workflow. A good name for your Open API token would be &lt;code&gt;OPEN_API_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create a Github Action
&lt;/h2&gt;

&lt;p&gt;With your API token ready, it's time to wire everything up into Github Actions. Our workflow should run whenever a PR is created or when new commits are pushed to an existing PR. When the workflow runs, it will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull down the changeset and then pass the changeset into our code review script.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://github.com/daves-dead-simple/open-ai-action" rel="noopener noreferrer"&gt;daves-dead-simple/open-ai-action&lt;/a&gt; to pass our prompt to Open AI&lt;/li&gt;
&lt;li&gt;Comment the output back to the original pr.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what a workflow file may look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLM Code Review&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;whichever-branch-you-want-code-review-for&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;opened&lt;/span&gt; &lt;span class="c1"&gt;# when a PR is opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;synchronize&lt;/span&gt; &lt;span class="c1"&gt;# when code is pushed to a pr&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;code-review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout PR branch&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get Diff&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;diff&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "changeset&amp;lt;&amp;lt;EOF" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class="s"&gt;echo "$(gh pr diff ${{ github.event.pull_request.number }} --repo "${{ github.repository }}")" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class="s"&gt;echo "EOF" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run AI code review&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;daves-dead-simple/open-ai-action@main&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;code-review&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;OPEN_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.OPENAI_API_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;Please code review the following changeset: ${{ steps.get_diff.outputs.changeset }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Comment on PR with AI review&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gh pr comment ${{ github.event.pull_request.number }} \&lt;/span&gt;
            &lt;span class="s"&gt;--repo "${{ github.repository }}" \&lt;/span&gt;
            &lt;span class="s"&gt;--body "${{ steps.code-review.outputs.completion }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow will run everytime a PR is open or updated (i.e., when new commits are pushed). It uses the github CLI to fetch the diff and then pass it along to Chat GPT along with instruction for what to &lt;em&gt;do&lt;/em&gt; with the changeset we are sending it. The LLM will in turn give us its response which we post back to the original PR.&lt;/p&gt;

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

&lt;p&gt;This is a very simple way to integrate OpenAI or any other LLM into your dev workflow. You can easily iterate on this idea to not only let users pick the model and provider of their choice, but even provide custom rules or instructions to the LLM.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>githubactions</category>
      <category>github</category>
    </item>
    <item>
      <title>Why Dead Code Is Hurting Your Team — and How to Fix It</title>
      <dc:creator>David</dc:creator>
      <pubDate>Mon, 27 Jan 2025 17:53:50 +0000</pubDate>
      <link>https://dev.to/daveturissini/why-dead-code-is-hurting-your-team-and-how-to-fix-it-31c9</link>
      <guid>https://dev.to/daveturissini/why-dead-code-is-hurting-your-team-and-how-to-fix-it-31c9</guid>
      <description>&lt;p&gt;Dead code is a silent form of technical debt, and it's slowing your team down. Dead code increases the complexity of your codebase which makes it harder to implement new features, improve existing functionality, or refactor code efficiently. Ignoring it can lead to slower development cycles, frustrated developers, and unnecessary costs.&lt;/p&gt;



&lt;h2&gt;
  
  
  What Is Dead Code?
&lt;/h2&gt;

&lt;p&gt;Dead code is any code in your codebase that isn’t actively used in your application. This could range anywhere from unused files all the way down to unused exports, dependencies, or even enum properties. While it might seem harmless at first, dead code contributes to clutter, confusion, and wasted effort. Removing it is crucial to maintaining a clean, efficient, and scalable codebase.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Hidden Costs of Dead Code
&lt;/h2&gt;

&lt;p&gt;The impact of dead code is often subtle but highly consequential. To understand its effects, let’s look at a simple example in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;unusedFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// does things&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;realFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// does things&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, imagine you need to change the value property from a &lt;code&gt;number&lt;/code&gt; to a &lt;code&gt;boolean&lt;/code&gt;. This small update forces you to modify both &lt;code&gt;realFunction&lt;/code&gt; and &lt;code&gt;unusedFunction&lt;/code&gt;—even though &lt;code&gt;unusedFunction&lt;/code&gt; isn’t being used anywhere in your code.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;unusedFunction&lt;/code&gt; is complex, you’ll spend critical dev cycles deciphering its purpose, dependencies, and downstream implications. Worse, you might need input from other developers to understand its original intent. All this extra work delays your task, increases development costs, and risks missing tight deadlines.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture: Dead Code Across Your Codebase
&lt;/h2&gt;

&lt;p&gt;Removing dead code requires a deliberate and systematic approach. Here are two main strategies to consider:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Manual Auditing
&lt;/h3&gt;

&lt;p&gt;One way to remove dead code is by manually reviewing your codebase. This approach works for smaller projects but quickly becomes impractical for larger codebases. It’s time-consuming, error-prone, and may lead to accidentally removing active code or missing significant dead code paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Automated Tools
&lt;/h3&gt;

&lt;p&gt;For larger projects, automating the detection and removal of dead code is a game-changer. Tools like &lt;a href="https://removeunused.com" rel="noopener noreferrer"&gt;remove-unused&lt;/a&gt; simplify this process by analyzing your TypeScript codebase, identifying unused files, and providing actionable reports.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;remove-unused&lt;/code&gt; works by inspecting your Typescript codebase. It builds your project's dependency graph by looking at all of your code's import and require statements. It then flags files that aren't referenced anywhere. This accounts for aliases or custom paths, and ensures unused code is accurately flagged.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;remove-unused&lt;/code&gt; is also designed to work seamlessly with modern frameworks like Next.js. It automatically recognizes critical directories such as app or pages and even supports MDX files.&lt;/p&gt;

&lt;p&gt;Using tools like &lt;code&gt;remove-unused&lt;/code&gt; to automatically remove dead code will save your team time, reduce errors, and allow your to focus on solving core business problems instead of wrestling with outdated code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Dead Code Shouldn’t Be Ignored
&lt;/h2&gt;

&lt;p&gt;Dead code isn’t just an annoyance—it’s a productivity killer. It adds complexity to your codebase, increases maintenance costs, and slows down feature delivery. Addressing dead code proactively improves code quality, boosts team morale, and accelerates development.&lt;/p&gt;

&lt;p&gt;Start cleaning up your codebase today. Whether you use manual auditing for small projects or automated tools like remove-unused for larger ones, taking action now will set your team up for success.&lt;/p&gt;

&lt;p&gt;Ready to eliminate dead code? Learn more at &lt;a href="https://removeunused.com" rel="noopener noreferrer"&gt;removeunused.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What's with the Weird Elixir Function Names</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 04 Jun 2024 05:08:28 +0000</pubDate>
      <link>https://dev.to/daveturissini/whats-with-the-weird-elixir-function-names-g75</link>
      <guid>https://dev.to/daveturissini/whats-with-the-weird-elixir-function-names-g75</guid>
      <description>&lt;p&gt;Have you ever noticed that in all of the documentation related to Elixir, functions are referenced like &lt;code&gt;function_name/2&lt;/code&gt;? This is by design- Elixir itself identifies functions by &lt;a href="https://hexdocs.pm/elixir/basic-types.html#identifying-functions-and-documentation"&gt;its name and the number of arguments it takes&lt;/a&gt;. The documentation, in turn, follows suite.&lt;/p&gt;

&lt;p&gt;So, whenever you see Elixir docs (or, ahem, error pages) referencing &lt;code&gt;function_name/2&lt;/code&gt;, you will know that it's referencing &lt;code&gt;function_name&lt;/code&gt; that accepts 2 arguments.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Rust vs Typescript Variables</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 04 Jun 2024 04:58:35 +0000</pubDate>
      <link>https://dev.to/daveturissini/rust-vs-typescript-variables-38ab</link>
      <guid>https://dev.to/daveturissini/rust-vs-typescript-variables-38ab</guid>
      <description>&lt;p&gt;Jumping into Rust from Typescript requires that you change the way you think about code.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Log Statement
&lt;/h2&gt;

&lt;p&gt;It is trivial to log a variable Typescript. Simply declare the variable and then pass it &lt;code&gt;console.log&lt;/code&gt;. This is totally fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't really matter what happens between the variable declaration and the log statement. The output will be logged as expect. For example, this is &lt;em&gt;also&lt;/em&gt; perfectly fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;otherValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;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;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both of these examples, &lt;code&gt;value&lt;/code&gt; is declared and then logged. There is nothing surprising here. In order to get this same functionality in Rust, we have to change our approach and the way we are thinking about the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ownership
&lt;/h2&gt;

&lt;p&gt;What happens if you do this in Rust?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;otherValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It certainly looks like &lt;code&gt;value&lt;/code&gt; will be logged, but what you actually get is a super fun compiler error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;move occurs because `value` has type `std::string::String`, which does not implement the `Copy` trait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it comes to variable assignments, Rust and Typescript come from completely different planets. In Typescript, it's perfectly fine to create variables, reassign them, and, in most cases, mutate them. You don't need to think about heaps, stacks, or how memory is cleaned up after the fact. The runtime handles all of that for you.&lt;/p&gt;

&lt;p&gt;Rust, on the other hand, &lt;em&gt;requires&lt;/em&gt; you to think about memory allocation, how you are accessing that memory, and how that memory gets cleaned up (sort of).&lt;/p&gt;

&lt;p&gt;In the Rust code above, we create a &lt;code&gt;String&lt;/code&gt; and assign it to the variable &lt;code&gt;value&lt;/code&gt;. &lt;code&gt;value&lt;/code&gt; now "owns" that string and, in Rust, values are only allowed to have one owner.&lt;/p&gt;

&lt;p&gt;When we assign &lt;code&gt;value&lt;/code&gt; to &lt;code&gt;otherValue&lt;/code&gt;, we aren't just copying the value or creating a reference to it like we would be doing in Typescript. Instead, we are transfering ownership or moving the &lt;code&gt;String&lt;/code&gt; to &lt;code&gt;otherValue&lt;/code&gt;. After the value is moved, we are no longer allowed to reference &lt;code&gt;value&lt;/code&gt;, and how could we? It no longer owns anything!&lt;/p&gt;

&lt;h2&gt;
  
  
  Borrowing
&lt;/h2&gt;

&lt;p&gt;Fortunately, changing "ownership" isn't the only way to assign values in Rust. Instead of changing ownership, we can have &lt;code&gt;otherValue&lt;/code&gt; "borrow" &lt;code&gt;value&lt;/code&gt;. All we need to do is add a &lt;code&gt;&amp;amp;&lt;/code&gt; to the assignment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;otherValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Borrowing!&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of taking full ownership of &lt;code&gt;value&lt;/code&gt;, &lt;code&gt;otherValue&lt;/code&gt; creates a pointer that points to the value of &lt;code&gt;value&lt;/code&gt;, which in this case is &lt;code&gt;String::from("string")&lt;/code&gt;. Because &lt;code&gt;otherValue&lt;/code&gt; is simply borrowing &lt;code&gt;value&lt;/code&gt;, we are free to continue referencing &lt;code&gt;value&lt;/code&gt; further along in our code.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Avoid This Common React Hook Antipattern</title>
      <dc:creator>David</dc:creator>
      <pubDate>Mon, 01 May 2023 16:04:45 +0000</pubDate>
      <link>https://dev.to/daveturissini/avoid-this-common-react-hook-antipattern-1eh1</link>
      <guid>https://dev.to/daveturissini/avoid-this-common-react-hook-antipattern-1eh1</guid>
      <description>&lt;p&gt;When displaying synchronous data in React components, &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; are antipatterns that should be avoided. Using &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; to compute synchronous values will lead to a sub-optimal user experience and subtle bugs that can be hard to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Consider the following component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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="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="nx"&gt;useEffect&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&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;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFullName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example we are computing &lt;code&gt;fullName&lt;/code&gt; from two props: &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;. Even though &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; are both available at render time, we are passing them both into a &lt;code&gt;useEffect&lt;/code&gt; hook. Inside the &lt;code&gt;useEffect&lt;/code&gt; hook, we are then concatenating the values and then calling &lt;code&gt;setFullName&lt;/code&gt; with the concatenated value.&lt;/p&gt;

&lt;p&gt;This is problematic for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useEffect&lt;/code&gt; runs &lt;em&gt;after&lt;/em&gt; the component renders and displays a value to the user. This means that the user will always see a stale value before the updated value is shown to the user.&lt;/li&gt;
&lt;li&gt;To see our computed value, we have to always render our component twice. On the first render, we display a stale value. When the &lt;code&gt;useEffect&lt;/code&gt; runs, it calls &lt;code&gt;setFullName&lt;/code&gt; which will trigger &lt;em&gt;another&lt;/em&gt; render.&lt;/li&gt;
&lt;li&gt;From a developer perspective, the logic is hard to read and hard to follow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;The fix for this pattern is simple. Instead of computing the values in a &lt;code&gt;useEffect&lt;/code&gt;, we can simply compute the values as part of the "natural" rendering process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&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;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullName&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="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lastName&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Computing the value during render has the following advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our component is &lt;em&gt;much&lt;/em&gt; simpler. We were able to completely eliminate any hook usage in our component.&lt;/li&gt;
&lt;li&gt;The user will never see a stale value. Everytime one of our props changes, it will be immediately reflected in the DOM.&lt;/li&gt;
&lt;li&gt;We've eliminated an extra render cycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;When you need to display computed value from synchronous data in React, it is almost always easier and safer to just compute the value in the component's body without &lt;code&gt;useEffect&lt;/code&gt; or &lt;code&gt;useState&lt;/code&gt;. This will lead to simpler components and a better user experience!&lt;/p&gt;

&lt;h2&gt;
  
  
  More Reading
&lt;/h2&gt;

&lt;p&gt;Interested to learn about Typescript? &lt;a href="https://languageimperfect.com/2019/08/05/understanding-typescript-type-predicates.html"&gt;Understanding Typescript’s Type Predicates&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Create and Run Your First Docker Image</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 23 Aug 2022 04:49:00 +0000</pubDate>
      <link>https://dev.to/daveturissini/how-to-create-and-run-your-first-docker-image-1kn3</link>
      <guid>https://dev.to/daveturissini/how-to-create-and-run-your-first-docker-image-1kn3</guid>
      <description>&lt;p&gt;I've spent the last few weeks diving into the world of Docker containers to understand how they work and how they can be improve our deployment process. While it was clear to me that Docker can provide a huge amount of value to our deployment and ops processes, it took me a while to understand exactly how to use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Images and Containers
&lt;/h2&gt;

&lt;p&gt;Docker has two main concepts that we need to understand: Images and Containers. Images define the environment you application needs in order to run. For node apps, this probably includes things like your source code, &lt;code&gt;node_modules&lt;/code&gt; directory, and &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files. For static apps, it may just include static HTML. For ruby apps, it may be your source plus your &lt;code&gt;bundle&lt;/code&gt; file. It all depends on your app.&lt;/p&gt;

&lt;p&gt;Images are built from your &lt;em&gt;source&lt;/em&gt; and pushed into repository, much like an NPM package or a Ruby gem. Once an image is built and published to a repository, anyone else on your team can pull that image down and use it to to create a &lt;em&gt;container&lt;/em&gt;, which is effectively just an &lt;em&gt;instance&lt;/em&gt; of our image.&lt;/p&gt;

&lt;p&gt;The important takeaway is that Images &lt;em&gt;define&lt;/em&gt; the application environment while Containers actually &lt;em&gt;run&lt;/em&gt; that environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Docker Image
&lt;/h2&gt;

&lt;p&gt;All Docker images are build from a &lt;code&gt;Dockerfile&lt;/code&gt;. A &lt;code&gt;Dockerfile&lt;/code&gt; is a file that just has a &lt;a href="https://docs.docker.com/engine/reference/builder/"&gt;set of commands&lt;/a&gt;{:target="_blank"} telling Docker how to "wrap" the application environment into a reusable Image that can be used to create containers. The contents of a &lt;code&gt;Dockerfile&lt;/code&gt; looks more or less just like a series of bash commands. These commands are executed when we run &lt;code&gt;$ docker build&lt;/code&gt; and the output of those commands makes up our image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerfile
&lt;/h2&gt;

&lt;p&gt;Your application's Dockerfile should live in your app's repo alongside the source code. It doesn't make a ton of sense for your Dockerfile to live outside of your application's repo since your Dockerfile will be responsible for creating an image that will be used to eventually run the application. Ultimately, the application developer is responsible for writing their own Dockerfile to create their image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your first Dockerfile
&lt;/h2&gt;

&lt;p&gt;Let's create a simple Dockerfile that only contains Nginx. Create a &lt;code&gt;Dockerfile&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;FROM&lt;/code&gt; command is almost always the first command in every &lt;code&gt;Dockerfile&lt;/code&gt;. It tells Docker that we are basing our image from an already existing image. In this case, we are pulling down the &lt;code&gt;nginx&lt;/code&gt; image and using it as the basis for our image.&lt;/p&gt;

&lt;p&gt;To build this image, run the following command. (Make sure that you are in the same directory as our new Dockerfile.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all we need to create our first image! If you run &lt;code&gt;$ docker images&lt;/code&gt; in your teminal, you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QZbkPw9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7rdbsgougm3k0y47f03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QZbkPw9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7rdbsgougm3k0y47f03.png" alt="docker images command output" width="880" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having our first image is great, but it's only the first step. Now, we need to use that image to create and run a &lt;em&gt;container&lt;/em&gt;. Run &lt;code&gt;$ docker images&lt;/code&gt; again. Take note of the &lt;code&gt;IMAGE ID&lt;/code&gt; (&lt;code&gt;c431399b6d03&lt;/code&gt; in the image above, we'll call it &lt;code&gt;&amp;lt;&amp;lt;HASHED_ID&amp;gt;&amp;gt;&lt;/code&gt;). Copy that ID from your terminal and then run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -p 8000:80 &amp;lt;&amp;lt;HASHED_ID&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command tells docker to create and run a container from our image with the ID &lt;code&gt;&amp;lt;&amp;lt;HASHED_ID&amp;gt;&amp;gt;&lt;/code&gt;. Now, open your browser and navigate to &lt;code&gt;http://localhost:8000&lt;/code&gt;. You should see the standard nginx splash screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w9aRV4KU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa8u9dz2wmcbvusldkk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w9aRV4KU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa8u9dz2wmcbvusldkk5.png" alt="nginx splash screen" width="880" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Viola! We are now running an Nginx container from an image we created!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tagging your Docker image
&lt;/h2&gt;

&lt;p&gt;You may be wondering about the &lt;code&gt;&amp;lt;&amp;lt;HASHED_ID&amp;gt;&amp;gt;&lt;/code&gt; part from the step above. When we run &lt;code&gt;docker build&lt;/code&gt;, Docker automatically assigns our image a generated ID so it can be referenced laster. While we can continue to use that ID, it isn't the best developer experience and it's not that easy to remember! When we build our image, we can create a Docker image with a human-readable &lt;code&gt;tag&lt;/code&gt;. Docker will still create our image with it's generated ID, but it will also tag that ID with whatever name we provide it. Let's rebuild our image and give it the tag &lt;code&gt;my-first-docker-image&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build -t my-first-docker-image .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run &lt;code&gt;$ docker images&lt;/code&gt; again, you will see that the &lt;code&gt;Repository&lt;/code&gt; field is now populated with &lt;code&gt;my-first-docker-image&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Er_MRkn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynag73c413xdmculeuxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Er_MRkn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynag73c413xdmculeuxn.png" alt="docker images command output with tagged image" width="880" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our run command from above can now be changed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -p 8000:80 my-first-docker-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much better!&lt;/p&gt;

&lt;h2&gt;
  
  
  In Summary
&lt;/h2&gt;

&lt;p&gt;Creating Images and running them in Containers is only scratching the surface for what Docker can do. Docker does have a bit of a learning curve, but once you get the hang of it, you won't be able to work without it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enjoy this article? &lt;a href="https://easywebdev.substack.com/"&gt;Subscribe to EasyWebDev!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Fetching Data in Svelte</title>
      <dc:creator>David</dc:creator>
      <pubDate>Wed, 17 Feb 2021 18:11:41 +0000</pubDate>
      <link>https://dev.to/daveturissini/fetching-data-in-svelte-1jpn</link>
      <guid>https://dev.to/daveturissini/fetching-data-in-svelte-1jpn</guid>
      <description>&lt;p&gt;I always find it frustrating when &lt;a href="http://bit.ly/2NxTxyW"&gt;I'm learning a new framework&lt;/a&gt; and I get to the point where I have to depart from my existing knowledge and principles in order to learn the framework's way of thinking. Frameworks should exist for developers and so it was refreshing to discover that Svelte is mostly unopinionated when it comes to fetching server data. This means that developers can focus on creating high-quality applications instead of learning “the Svelte way” of fetching data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech
&lt;/h2&gt;

&lt;p&gt;Because Svelte doesn't have an out of the box solution for fetching data, it is possible to use almost any existing library to fetch data in your Svelte component. Even though almost everything is possible, &lt;code&gt;fetch&lt;/code&gt; and &lt;code&gt;XMLHTTPRequest&lt;/code&gt; are the easiest ways to fetch data in your Svelte component. In this article, I will examine specifically how we can use &lt;code&gt;fetch&lt;/code&gt; to load data from the &lt;a href="https://swapi.dev/"&gt;The Star Wars API&lt;/a&gt;, a publicly accessible API for Star Wars data.&lt;/p&gt;

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

&lt;p&gt;You can find working examples of all the code in this article &lt;a href="http://bit.ly/3jVywu9"&gt;on github&lt;/a&gt;: &lt;a href="https://github.com/davidturissini/svelte-data-demo"&gt;https://github.com/davidturissini/svelte-data-demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone the repo and then run &lt;code&gt;npm install &amp;amp;&amp;amp; npm run dev&lt;/code&gt;. The app will be running at &lt;code&gt;http://localhost:5000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After reading this article you will be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load server data in your Svelte component&lt;/li&gt;
&lt;li&gt;Load server data inside Svelte's &lt;code&gt;onMount&lt;/code&gt; lifecycle hook&lt;/li&gt;
&lt;li&gt;Display a loading screen while data is being loaded&lt;/li&gt;
&lt;li&gt;Load data on-demand from a user interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This article only covers fetching data for your Svelte components. If you are interested to learn more about Svelte and state management, be sure to follow me to get notified when that article gets published!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Using Fetch with Svelte
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://bit.ly/3bdIeE5"&gt;Code on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The easiest way to use &lt;code&gt;fetch&lt;/code&gt; in your Svelte component is to simply invoke &lt;code&gt;fetch&lt;/code&gt; directly in your component's &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag. &lt;a href="http://bit.ly/2NxTxyW#reactivity"&gt;You'll recall that Svelte's reactivity model&lt;/a&gt; works by referencing a &lt;code&gt;let&lt;/code&gt; variable directly in your component's HTML. Whenever the variable gets a new value, Svelte will automatically re-render that new value.&lt;/p&gt;

&lt;p&gt;With a modified approach, we can use this same functionality to render the contents of a &lt;code&gt;fetch&lt;/code&gt; response. Instead of immediately assigning a value to our &lt;code&gt;let&lt;/code&gt; variable, we instead dispatch a &lt;code&gt;fetch&lt;/code&gt; request. We then populate our variable with values from our response once it settles. Our new values will then automatically be rendered into our HTML and become visible to the user.&lt;/p&gt;

&lt;p&gt;For example, to display Luke Skywalker's name in a Svelte component, we can create the variable &lt;code&gt;characterName&lt;/code&gt; and then make a &lt;code&gt;fetch&lt;/code&gt; call to &lt;code&gt;https://swapi.dev/api/people/1&lt;/code&gt;. After our response is settled, we can then assign &lt;code&gt;character.name&lt;/code&gt; to &lt;code&gt;characterName&lt;/code&gt;. Since &lt;code&gt;characterName&lt;/code&gt; is referenced in our HTML, Svelte will render the value for us. Fairly simple!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;character&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;characterName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    {characterName}
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is not limited to just &lt;code&gt;fetch&lt;/code&gt;. If we wanted to, we could create a Redux subscription and update &lt;code&gt;characterName&lt;/code&gt; whenever we are passed a new value. We could also create a GraphQL subscription and follow the same pattern. As long as we can update variables that are in our HTML, Svelte will continue rendering the latest data no matter how we received those values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component onMount
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://bit.ly/3jUye6I"&gt;Code on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Executing &lt;code&gt;fetch&lt;/code&gt; in your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag works well if you know that your component will always run in the browser. If it is even remotely possible that your component will be server rendered, we need to find a different approach. The biggest drawback with invoking &lt;code&gt;fetch&lt;/code&gt; directly in your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; that &lt;code&gt;fetch&lt;/code&gt; will also be invoked when your component is rendered on the server. This could lead to some noticeable performance problems, both for your users and your servers.&lt;/p&gt;

&lt;p&gt;We can improve our approach above by invoking our &lt;code&gt;fetch&lt;/code&gt; call inside of &lt;a href="https://svelte.dev/tutorial/onmount"&gt;Svelte's onMount lifecycle hook&lt;/a&gt;. With the exception of &lt;code&gt;onDelete&lt;/code&gt;, Svelte lifecycle hooks are never invoked on the server, so putting our &lt;code&gt;fetch&lt;/code&gt; call inside of an &lt;code&gt;onDelte&lt;/code&gt; hook guarantees that we will only call our APIs when the component is rendered in the browser. This will reduce your server load because we are only making our &lt;code&gt;fetch&lt;/code&gt; call once the component is rendered in the browser. It also reduces time to serve because our server code does not have to wait for our data to settle before sending something back to the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;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;onMount&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;svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;onMount&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1&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;character&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;characterName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    {characterName}
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handle Loading States
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://bit.ly/3bh3j0m"&gt;Code on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even if we use &lt;code&gt;onMount&lt;/code&gt; to fetch server data, we aren't quite giving our users the best possible experience. Because &lt;code&gt;characterName&lt;/code&gt; is not initialized with a default value, Svelte will render text &lt;code&gt;"undefined"&lt;/code&gt; while our app fetches our data. Not ideal!  We could avoid this by giving &lt;code&gt;characterName&lt;/code&gt; some default value that is displayed while we fetch our data. That approach would work, and it would definitely be a better experience, but I think using an &lt;a href="https://svelte.dev/tutorial/else-if-blocks"&gt;if-else conditional&lt;/a&gt; in our HTML to add a spinner would be an even better user experience. This approach is pretty powerful because there is no limit to what you can display while data is being fetched. It can be some simple text or it can be a complex Svelte component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;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;onMount&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;svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;onMount&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1&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;character&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;characterName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;character&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    {#if characterName === undefined}
        Loading Character Name...
    {:else}
        {characterName}
    {/if}
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lazy HTTP Requests
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://bit.ly/3puPPmE"&gt;Code on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Invoking our &lt;code&gt;fetch&lt;/code&gt; call inside of &lt;code&gt;onMount&lt;/code&gt; means that every time our component mounts, we are going to make a server request. This is not always the correct behavior. Sometimes, we might want to wait for our users to give us a signal that they are ready for some data to be loaded. In this case, we can give our users some sort of UI, like a button, to control when our &lt;code&gt;fetch&lt;/code&gt; call is invoked.&lt;/p&gt;

&lt;p&gt;Instead of invoking our fetch call directly in &lt;code&gt;onMount&lt;/code&gt;, we can make our &lt;code&gt;fetch&lt;/code&gt; request lazy by moving it inside of a function that can be used as &lt;a href="http://bit.ly/2NxTxyW#event-handling"&gt;an event handler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Making our &lt;code&gt;fetch&lt;/code&gt; request lazy is a nice performance win. It reduces our server load and perceived user performance because we are not consuming memory or server resources with data that our user may never use. It &lt;em&gt;also&lt;/em&gt; exposes an assumption that we made in our code. Up until now, all of our code samples have assumed that we are either making an HTTP request or the HTTP request has settled. Making our &lt;code&gt;fetch&lt;/code&gt; lazy means that it is possible for our code to be idle. In our case, our idle state is just a period of time before the initial &lt;code&gt;fetch&lt;/code&gt; request is triggered. In this state, we don't need to show a loading indicator and we don't yet have data to show the user so we need to update our code to handle this new behavior. There are many approaches that we could use, but the easiest way is to simply move &lt;code&gt;characterName&lt;/code&gt; and &lt;code&gt;loading&lt;/code&gt; into a tuple. We can then update our HTML conditional to not show our loading screen if &lt;code&gt;loadig&lt;/code&gt; is false AND &lt;code&gt;characterName&lt;/code&gt; is not present.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://swapi.dev/api/people/1&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;character&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;characterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;character&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="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{loadData}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Load Data&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    {#if data.loading === true}
        Loading Character Name...
    {:else if data.characterName !== undefined}
        {data.characterName}
    {/if}
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our component waits for our user to click on our &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; before making an HTTP request. This is also a good pattern for making create, update, or delete server calls. We certainly wouldn't want our component to be mutating data every time it loads!&lt;/p&gt;

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

&lt;p&gt;Svelte is very flexible when it comes to fetching data for your application. By and large, you bring whichever tools you are comfortable with and you don't need to reinvent the wheel to render your data. The easiest approach to loading data is by using &lt;code&gt;fetch&lt;/code&gt; in our &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag but the most robust way to fetch data is to use &lt;code&gt;onMount&lt;/code&gt;. Svelte also makes it easy to render a loading screen while our data is being fetched and to make our &lt;code&gt;fetch&lt;/code&gt; requests lazy which improves our application’s overall performance. If there are any other tips or suggestions, feel free to leave them in the comments below!&lt;/p&gt;

&lt;p&gt;Don't forget to FOLLOW if you want to get more Svelte tutorials and deep dives as soon as they are published!&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>My First Impressions of Svelte</title>
      <dc:creator>David</dc:creator>
      <pubDate>Mon, 01 Feb 2021 16:04:53 +0000</pubDate>
      <link>https://dev.to/daveturissini/my-first-impressions-of-svelte-3edl</link>
      <guid>https://dev.to/daveturissini/my-first-impressions-of-svelte-3edl</guid>
      <description>&lt;p&gt;After hearing a lot about Svelte over the last few months, I've finally decided to take the plunge and give it a try. Since this is my first time playing with Svelte, I wanted to publish my initial thoughts to hopefully help anyone curious about what Svelte has to offer.&lt;/p&gt;

&lt;p&gt;This isn't meant to be a tutorial on Svelte, it is simply my reaction to looking at Svelte for the first time. If you haven't already, &lt;a href="https://svelte.dev/tutorial/"&gt;be sure to check it out&lt;/a&gt;. It is a simple way to get started working with Svelte. Most (if not all) of the code examples are lifted straight from the Svelte tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Svelte?
&lt;/h2&gt;

&lt;p&gt;In its own words, &lt;a href="https://svelte.dev/"&gt;Svelte&lt;/a&gt; "is a radical new approach to building user interfaces." In my words, Svelte is a component-based framework for building websites and web apps.&lt;/p&gt;

&lt;p&gt;Conceptually, Svelte appears to share a lot of concepts with React and Vue, however, those are only surface level appearances. Svelte introduces a new way of thinking about components, and a unique set of features that allow you to create high quality components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Absolute First Impression
&lt;/h2&gt;

&lt;p&gt;After spending about half an hour on Svelte's playground, I can say that I very much enjoy the framework's ergonomics, how it approaches building components, and its general philosophy. I also like that accessibility is a first class citizen. For example, if you create an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; without an &lt;code&gt;alt&lt;/code&gt; attribute, the Svelte compiler will give you a clear, actionable warning. This is a great feature that hopefully will go a long way towards better application accessibility.&lt;/p&gt;

&lt;p&gt;The code that the Svelte compiler outputs is surprisingly &lt;em&gt;clean&lt;/em&gt;. When a compiler is involved, it usually means that the output code is not entirely human readable. Not so with Svelte. Most of the outputted code looks as if it could have been written by a human, which means that the run time code should be very debuggable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;I haven't taken a deep dive into Svelte's architecture, but at a high level Svelte components are written with HTML, CSS and Javascript. Those templates are then compiled into code that can be executed in your browser. Svelte templates really, really want to be fully declarative. They want to let the developer forget all about rendering and render cycles. This is really good news for developers because it allows us to focus on our business problem and not on the details of rendering our components. We can simply &lt;em&gt;declare&lt;/em&gt; the data we need and delegate the work to Svelte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a Svelte Component
&lt;/h2&gt;

&lt;p&gt;Svelte component files behave just like a plain HTML document. Just like any HTML document, you use &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags to add styles and interactivity. I think the plain HTML, CSS and Javascript model is one of Svelte's most powerful features. Writing scalable and performant apps using familiar HTML, CSS, and Javascript is pretty compelling. In fact, if your application does not require any component level css or javascript, it is entirely feasible that your Svelte app could just be HTML. That's pretty neat!&lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring Javascript Variables
&lt;/h2&gt;

&lt;p&gt;Adding Javascript to your component is as easy as adding a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to your template file. Everything inside your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag is scoped to your component so you don't have to worry about naming or state collisions outside of your component.&lt;/p&gt;

&lt;p&gt;Any variable declared in your template file can be referenced in your HTML using bracket notation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buttonText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;{buttonText}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{buttonText}&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in your Svelte components are a superset of standard &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags. You are able to use any standard Javascript in your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag including ternarys, function calls, and even &lt;code&gt;import&lt;/code&gt; statements. In addition to standard Javascript, Svelte introduces some domain-specific concepts like declarations and statements that you can use to enhance your component.&lt;/p&gt;

&lt;p&gt;I find &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; usage intuitive because it is already a concept that I am familiar with. It also more or less aligns with how I think about Javascript in template files in general. This approach also becomes &lt;em&gt;very&lt;/em&gt; interesting in terms of how Svelte handles reactivity and component state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Handling
&lt;/h2&gt;

&lt;p&gt;I find Svelte's approach to event handling intuitive as well. Adding an event listener is fairly simple. You can create an event handler in your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag and then reference that function in your HTML using an attribute prefixed with &lt;code&gt;on:&lt;/code&gt;. For example, in the code below, &lt;code&gt;handleClick&lt;/code&gt; will be executed every time our button is clicked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buttonText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// handle click event&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{handleClick}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{buttonText}&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reactivity
&lt;/h2&gt;

&lt;p&gt;Reactivity is essentially how your components and app respond to changes over time. Svelte handles reactivity bindings during compilation, not during runtime. Because Svelte understands where your Javascript variables are referenced in your HTML, it can generate efficient bindings ahead of time. This means you don't need to waste run time CPU to understand what is reactive and what isn't. Svelte takes care of this well before you execute any code.&lt;/p&gt;

&lt;p&gt;Svelte attempts to add reactivity as transparently as possible. There is no special syntax to make a value reactive. All you have to do is reference the value in your HTML. This makes adding reactivity in Svelte fairly straightforward. It &lt;em&gt;does&lt;/em&gt; mean that we are adding side effects to what would otherwise be a simple variable declaration. I might be overthinking things a bit, but foot-guns here are not inconceivable.&lt;/p&gt;

&lt;p&gt;Because Svelte's compiler handles generating reactivity bindings for you, making a variable reactive is straightforward. You only have to reference the value in your HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buttonCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;buttonCount&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;on:click=&lt;/span&gt;&lt;span class="s"&gt;{handleClick}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{buttonCount}&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time our button is clicked, our &lt;code&gt;buttonCount&lt;/code&gt; variable is incremented and our new value is rendered. You simply &lt;em&gt;declare&lt;/em&gt; that you want to display the value for &lt;code&gt;buttonCount&lt;/code&gt; and Svelte generates code that handles the binding for you. Svelte makes it easy to bind values to HTML, but its reactivity model extends to Javascript values as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarations
&lt;/h2&gt;

&lt;p&gt;Declarations are the first feature that truly feels like something only Svelte offers. I think declarations are the most interesting feature of Svelte. Declarations allow you to create composable data streams that can be reflected into your HTML.&lt;/p&gt;

&lt;p&gt;You can create a declaration inside your &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag with new grammer introduced by : &lt;code&gt;$: NAME = VALUE&lt;/code&gt;.  The &lt;code&gt;$: NAME&lt;/code&gt; creates a reactivity binding that listens to changes to &lt;code&gt;VALUE&lt;/code&gt;. Every time &lt;code&gt;VALUE&lt;/code&gt; changes, &lt;code&gt;NAME&lt;/code&gt; will be updated. All references to &lt;code&gt;NAME&lt;/code&gt; in HTML will then be updated as expected.&lt;/p&gt;

&lt;p&gt;Composing declarations is as easy as using a &lt;code&gt;+&lt;/code&gt; operator. &lt;code&gt;$: NAME = VALUE + OTHER&lt;/code&gt; will cause &lt;code&gt;NAME&lt;/code&gt; to be updated if &lt;code&gt;VALUE&lt;/code&gt; &lt;em&gt;or&lt;/em&gt; &lt;code&gt;OTHER&lt;/code&gt; ever changes.&lt;/p&gt;

&lt;p&gt;I love this feature because it allows you to declaratively create really complex datastreams without much effort. Aside from the new syntax, creating a declaration is almost exactly the same as creating a plain variable. Really neat!&lt;/p&gt;

&lt;h2&gt;
  
  
  Statements
&lt;/h2&gt;

&lt;p&gt;Svelts statements are like declarations except they add reactivity to entire Javascript statements, not just variables. For example, this means that we can make an if-conditional recompute every time a value within its block changes.&lt;/p&gt;

&lt;p&gt;This is another feature that I absolutely love. In effect, it allows you to declaratively create reactive routines which can then be piped to other declarations or statements. Really good stuff!&lt;/p&gt;

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

&lt;p&gt;I will definitely be exploring using more of Svelte in the future. I think the intuitive component model plus the innovative declaration + statement features create a compelling case for using Svelte for some of my projects going forward. If you're curious about Svelte, head on over &lt;a href="https://svelte.dev"&gt;to their website&lt;/a&gt; to get an even more detailed look about how Svelte works.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Enjoyed this article? Head on over to &lt;a href="https://easywebdev.substack.com/"&gt;Easy Web Dev&lt;/a&gt; and &lt;a href="https://easywebdev.substack.com/subscribe"&gt;SUBSCRIBE&lt;/a&gt; to get access to in-depth web development tutorials and walk-throughs.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How Typescript Generics Work</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 19 Jan 2021 06:31:00 +0000</pubDate>
      <link>https://dev.to/daveturissini/typescript-generics-primer-470m</link>
      <guid>https://dev.to/daveturissini/typescript-generics-primer-470m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The following article is a free sample from &lt;a href="https://easywebdev.substack.com/"&gt;EasyWebDev&lt;/a&gt; mailing list. &lt;a href="https://easywebdev.substack.com/"&gt;Subscribe&lt;/a&gt; to get simple web development guides, tutorials, and explanations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you've been using Typescript, there is a good chance that you've come across &lt;a href="https://www.typescriptlang.org/docs/handbook/generics.html"&gt;Generics&lt;/a&gt;. Generics are a handy Typescript feature that allows you to declare variable types for your interfaces, types, and declarations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;T&lt;/code&gt; is a Generic that allows the &lt;em&gt;consumer&lt;/em&gt; to specify the type for our property &lt;code&gt;prop&lt;/code&gt;. This is handy in situations where all the possible types are not known ahead of time or where there are a wide variety of types that we don't need to constrain on the interface level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Generics
&lt;/h2&gt;

&lt;p&gt;Using generics in your application code is conceptually very similar to passing arguments to to your functions. However, instead of passing run time values, we are passing Typescript type definitions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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;Generics make our code more flexible but they still also guarantee type safety.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&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="c1"&gt;// Error! string is passed to the generic, but a number is specified.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Non-Trivial Types
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complex Types
&lt;/h3&gt;

&lt;p&gt;The values passed to a Generic do not need to be simple types. Any valid Typescript expression is allowed. The important take-away is that the concrete value must adhere to the Generics' type, whatever it is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;unionObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&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="c1"&gt;// this can be either a string or a number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeofObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// this can only be an object that matches the type from window.document&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple Generics
&lt;/h3&gt;

&lt;p&gt;There is no limit to the number of generics that you can define for a given interface, type, or declaration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="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="nx"&gt;B&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;prop&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="nl"&gt;next&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="nl"&gt;another&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Default Types
&lt;/h2&gt;

&lt;p&gt;When a generic is defined, the caller always has to specify a type for the generic. To get around this requirement, Generics can be assigned default types. When a default type is used and a type has not been specified, Typescript will use the default Generic type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;string&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;prop&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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;Default types allow you to do some very complex and interesting inference. Here is a silly example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&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;a&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="nl"&gt;b&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;// Error! b MUST match the type from a.prop.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Constraining Generics
&lt;/h2&gt;

&lt;p&gt;By default there are no constraints on the types that can be passed to a Generic. Sometimes, however, we want to constrain a Generic's type. One way we can do this is aliasing the constraint to a new type. This applies a localized constraint and does not globally constraint the Generic's type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Constrained&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;function&lt;/span&gt; &lt;span class="nx"&gt;myfunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Constrained&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another way to constraing Generics is on the Generic's definition itself. This constraint will apply to &lt;em&gt;any&lt;/em&gt; usage of the Generic, so all callers will need to adhere to the constraint when using &lt;code&gt;extends&lt;/code&gt; directly in the Generic's definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GenericInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&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;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Naming Generics
&lt;/h2&gt;

&lt;p&gt;This is a &lt;a href="https://twitter.com/kentcdodds/status/1348016701632221184"&gt;somewhat controversial&lt;/a&gt; topic, but there is a long-standing convention to use single letter names for your Generics. I would encourage you to use whatever approach works best for your team and application.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Enjoy this article? &lt;a href="https://easywebdev.substack.com/"&gt;Subscribe to EasyWebDev!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Aha! Understanding Typescript's Type Predicates</title>
      <dc:creator>David</dc:creator>
      <pubDate>Mon, 05 Aug 2019 16:47:48 +0000</pubDate>
      <link>https://dev.to/daveturissini/aha-understanding-typescript-s-type-predicates-40ha</link>
      <guid>https://dev.to/daveturissini/aha-understanding-typescript-s-type-predicates-40ha</guid>
      <description>&lt;p&gt;This article will cover Type Predicates at a high level. To understand Type Predicates, we must first understand how they are used in relation to union types. &lt;/p&gt;

&lt;h2&gt;
  
  
  Union Types
&lt;/h2&gt;

&lt;p&gt;In Typescript, a variable isn't always restricted to a single type. &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types"&gt;Union Types&lt;/a&gt; are a way to declare  multiple types onto a single value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// value can now be set to a `string`, `boolean`, or `null` value. &lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;numberOfLives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;isAGoodBoy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we use union types, we have to do work to &lt;em&gt;narrow&lt;/em&gt; the possible types down to the current value's actual type. &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types"&gt;Type Guards&lt;/a&gt; are what allow us to do this narrowing. &lt;/p&gt;

&lt;h2&gt;
  
  
  Type Guards
&lt;/h2&gt;

&lt;p&gt;According to the official docs, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A type guard is some expression that performs a runtime check that guarantees the type in some scope.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Put another way, type guards guarantee that a string is a string when it could also be a number.&lt;/p&gt;

&lt;p&gt;Type guards are not entirely different than doing feature detection. The big idea is to try to detect properties, methods or prototypes to figure out how to handle a value. There are four main ways to use type guards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;in&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;typeof&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;instanceof&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;type predicates with custom type guard&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Type Predicate
&lt;/h2&gt;

&lt;p&gt;While you are probably familiar with "in", "typeof", and "instanceof", you might be wondering what "type predicates" are. Type predicates are a special return type that signals to the Typescript compiler what type a particular value is. Type predicates are always attached to a function that takes a single argument and returns a boolean. Type predicates are expressed as &lt;code&gt;argumentName is Type&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Cat {
  numberOfLives: number;
}
interface Dog {
  isAGoodBoy: boolean;
}

function isCat(animal: Cat | Dog): animal is Cat {
  return typeof animal.numberOfLives === 'number';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For sample function, &lt;code&gt;isCat&lt;/code&gt;, is executed at run time just like all other type guards. Since this function returns a boolean and includes the type predicate &lt;code&gt;animal is Cat&lt;/code&gt;, the Typescript compiler will correctly cast the &lt;code&gt;animal&lt;/code&gt; as &lt;code&gt;Cat&lt;/code&gt; if &lt;code&gt;isCat&lt;/code&gt; evaluates as true. It will &lt;em&gt;also&lt;/em&gt; cast &lt;code&gt;animal&lt;/code&gt; as &lt;code&gt;Dog&lt;/code&gt; if &lt;code&gt;isCat&lt;/code&gt; evaluates as false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="o"&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;isCat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// animal successfully cast as a Cat&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// animal successfully cast as a Dog&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Pretty neat! Perhaps the best thing about custom type guards and type predicates is not only we can use &lt;code&gt;in&lt;/code&gt;, &lt;code&gt;instanceof&lt;/code&gt;, and &lt;code&gt;typeof&lt;/code&gt; in our type guards but we can also custom type checks. As long as our function returns a boolean, Typescript will do the right thing. &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What do you work on when you are on a plane? ✈️✈️</title>
      <dc:creator>David</dc:creator>
      <pubDate>Tue, 30 Jul 2019 22:41:17 +0000</pubDate>
      <link>https://dev.to/daveturissini/what-do-you-work-on-when-you-are-on-a-plane-1m96</link>
      <guid>https://dev.to/daveturissini/what-do-you-work-on-when-you-are-on-a-plane-1m96</guid>
      <description>&lt;p&gt;I’m about to spend a few hours on a plane as I head to our quarterly planning.&lt;/p&gt;

&lt;p&gt;I’ll probably spend the time working on a blog post and maybe a side project.&lt;/p&gt;

&lt;p&gt;What do you work on when your flying?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Code Golf Challenge: Palindrome Detector</title>
      <dc:creator>David</dc:creator>
      <pubDate>Thu, 25 Jul 2019 18:25:42 +0000</pubDate>
      <link>https://dev.to/daveturissini/code-golf-challenge-palindrome-detector-2kbi</link>
      <guid>https://dev.to/daveturissini/code-golf-challenge-palindrome-detector-2kbi</guid>
      <description>&lt;p&gt;Challenge: Using Javascript, implement a method that detects if a string is a palindrome in as few characters as possible!&lt;/p&gt;

&lt;p&gt;The goal of this exercise is to write as little code as possible. Readability and maintainability are not a concern!&lt;/p&gt;

&lt;p&gt;Solutions in comments 👇👇&lt;/p&gt;

</description>
      <category>codegolf</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>challenge</category>
    </item>
  </channel>
</rss>
