<?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: Jake Varness</title>
    <description>The latest articles on DEV Community by Jake Varness (@jvarness).</description>
    <link>https://dev.to/jvarness</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%2F40990%2F4ddfa5ce-ce30-4fd5-a5f3-45f6f459b447.jpeg</url>
      <title>DEV Community: Jake Varness</title>
      <link>https://dev.to/jvarness</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jvarness"/>
    <language>en</language>
    <item>
      <title>Adding Social Media Images to a Gatsby Site</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Fri, 17 May 2024 00:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/adding-social-media-images-to-a-gatsby-site-3llh</link>
      <guid>https://dev.to/jvarness/adding-social-media-images-to-a-gatsby-site-3llh</guid>
      <description>&lt;p&gt;When you post links on social media, sometimes the links generate a card that looks really really nice. I say sometimes because… Well… My blog never had good ones. I basically took that little “JV” logo I made in Gimp and set that as the image. It &lt;em&gt;worked&lt;/em&gt;, but it wasn’t &lt;em&gt;great&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When my links get posted online, I wanted to make sure that they looked at least somewhat professional. I may be the only one ever posting them, but I at least wanted them to look good! Not just a couple letters.&lt;/p&gt;

&lt;p&gt;So today, I’m going to tell you about the methods I researched to be able to add social media images to my site, and how I landed on using a Gatsby plugin called &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-plugin-satorare/" rel="noopener noreferrer"&gt;gatsby-plugin-satorare&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative Solutions
&lt;/h2&gt;

&lt;p&gt;Let’s start off by pointing out how others solved this: there are quite a few people who have solved this issue in the past, and many of the solutions involve a similar process: build a component using React that you will use in tandem with puppeteer to be able to render the images in a browser window and then have it take a screenshot of the preview page. Here were some of the posts that I had found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.emgoto.com/gatsby-react-social-card/" rel="noopener noreferrer"&gt;Emma Goto - “Generate custom social card images for your Gatsby blog”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://danspratling.dev/blog/automatically-generating-a-social-image-in-gatsby" rel="noopener noreferrer"&gt;Dan Spratling - “Automatic social images in Gatsby”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.maxpou.fr/blog/generate-social-image-share-with-gatsby/" rel="noopener noreferrer"&gt;Max Poutard - “How to generate social share images with Gatsby”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These solutions work just fine, so if for whatever reason you don’t like the way that I did this, you could try one of these. These solutions do have an easy way for you to test out that your generator is working. The solution I used did not have the easiest way of testing out that things worked, but once I got it working it’s smooth sailing.&lt;/p&gt;

&lt;p&gt;In doing the research for which plugin/solution I ultimately wanted to use, I went to search for plugins on Gatsby for social images, and&lt;code&gt;gatsby-plugin-satorare&lt;/code&gt; came up as a potential option. It uses another library from Vercel called &lt;a href="https://github.com/vercel/satori" rel="noopener noreferrer"&gt;&lt;code&gt;satori&lt;/code&gt;&lt;/a&gt; that can take JSX syntax and convert it into an image. They also have this really great&lt;a href="https://og-playground.vercel.app/" rel="noopener noreferrer"&gt;Playground&lt;/a&gt; where you can take the code you want to use to generate the image and you can test out how the end product looks. If I were you, and you want to use &lt;code&gt;gatsby-plugin-satorare&lt;/code&gt;, I would probably start there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OG Image Playground
&lt;/h2&gt;

&lt;p&gt;Vercel’s OG Image Playground uses &lt;code&gt;satori&lt;/code&gt; to be able to generate images using JSX syntax. However, this library does have it’s limitations in terms of the types of styling that it supports. Before diving into this, I would recommend taking a look at the &lt;a href="https://github.com/vercel/satori?tab=readme-ov-file#css" rel="noopener noreferrer"&gt;list of supported CSS properties&lt;/a&gt;that you can use to create an image. One of the things I ran into when I was doing this was that border styles weren’t working the way I expected them to.&lt;/p&gt;

&lt;p&gt;My blog uses border styles quite a bit to make some of the elements look like they have slanted edges. For example, this is the style used in a couple of different places on the site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;border-left: 3em solid transparent
border-bottom: 3em solid #e5e02d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using combinations of &lt;code&gt;border-*&lt;/code&gt; styles and defining one as a solid colored border and the other as a solid transparent border, you can cut a little of the colored border off on either side. I wanted to use this type of styling in my images, but &lt;code&gt;satori&lt;/code&gt; doesn’t have the ability to do this when it’s generating the images.&lt;/p&gt;

&lt;p&gt;If you wanted to try playing around with this effect, try heading to this &lt;a href="https://codepen.io/jvarness/pen/ExJqKVL" rel="noopener noreferrer"&gt;codepen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you were to try this same effect in the playground, however, you would notice that this simply doesn’t work. I’m assuming this is because of how satori works: it converts JSX syntax into an SVG, and I’m guessing that the translation from CSS styles to SVGs isn’t perfect.&lt;/p&gt;

&lt;p&gt;The workaround I used was that I just essentially created a little box that was filled with a black color that would cut off a little piece off the end of the date line on my images, and that ends up working ok.&lt;/p&gt;

&lt;p&gt;If you want to see the actual HTML/JSX I’m using to generate the image, I was able to create a shareable link on the &lt;a href="https://og-playground.vercel.app/?share=nVXfT9swEP5XLE-TNqk0TWgHimAPbEOaNKRp8JiHOvUlMTh2ZDtAV_V_n52fdVu2QV_q3J3Pd9_3-bzBK0kBx_iCssdEIKTNmsPlZuPWCFGmK07WMVpmHJ6Xk9bq1l-ZgpVhUljfSvK6FL33iVFTWGsYzWbVsKcAlhfGmj-d7lhTsnrIlawF_SK5VDFKcMqtLcF9gFQUGruWnFEULqpn9A4WMIvoXtAvQlmtXWhkgwZnRShlInf2UyhROF1AOTgzKcw1KRm3LSb4ijPxcENWt2ttoLy2vi5wu03EZ7e4KMIBIWTbbkse62kS3rLf4Mxzd5Dd2-xEaLO8NXWWLW0umygowi5j9P8ZbQN-xhupwG7fTRu1aTs69wndoTTBjscBih7GO1n1WLWQ76M9cjkbLB3nCT5bvB8CHWoIdbXaPvvg_YrQ2LdPfkOf1KyVWYIVcGLYI3gBqTRGls4dTs92uXW_kqiciR-Q2WoT7FHf099jG3m-tvaheoR-SqsJiqRAN2SN5qbo2uoB34X8WIseuLaODtzDhgco94vtUT_0GEWEzqRqUFDSEAMf5gsK-ccXoSSpPb82PpSmre5kbm-o5-AdgOfuRh9D6SKwzbfCG1dvkGDLV0Om1-M_Su81MApS7Su0xf9qEEtk58hxfb9BtodXBCHCWS6-2znSjCTX5wkIP-QV8rt_JEqA1tOUy_xQeqzsjLZMtbpMcGFMpeMg8PYFrCQ56KBca-DZ9L6CPMHeFb7chNF5d3avON_2krLH6buYjSPgb5weDvdjs33EIvD01f7jCZaVE4bG8QY3LeDYPTwT3BaPY_veTDCFtM5xnBGuYYKhlPfsbl25d888NV82kWPjW5kCxbFRNWwn2JDURhTAuXySilO8_QM" rel="noopener noreferrer"&gt;OG Playground&lt;/a&gt; where you can see it.&lt;/p&gt;

&lt;p&gt;Once I had the image working, it was time to configure the plugin!&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring &lt;code&gt;gatsby-plugin-satorare&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The first thing you’re going to want to do is create a small JavaScript file that acts as the “component” of the image. I say “component” because it’s not so much a React component as much as it’s just something that uses JSX syntax to define how the image is supposed to look.&lt;/p&gt;

&lt;p&gt;You’ll want this file to &lt;code&gt;export default&lt;/code&gt; a &lt;code&gt;function&lt;/code&gt; that takes an argument that is a Gatsby &lt;code&gt;Node&lt;/code&gt;. You can change the behavior of how the image is rendered based on the type of node it is. In my case, all of my blog posts are generated using the &lt;a href="https://www.gatsbyjs.com/plugins/gatsby-transformer-remark/" rel="noopener noreferrer"&gt;&lt;code&gt;gatsby-transformer-remark&lt;/code&gt;&lt;/a&gt; plugin, so they are all of type &lt;code&gt;MarkdownRemark&lt;/code&gt;. I decided not to generate images for all of the pages yet, so I’m only configuring the plugin to target&lt;code&gt;MarkdownRemark&lt;/code&gt; nodes. In the end, this is how my little component looked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/components/social-image-card.js
export default function (node) {
  const postedDate = new Date(node.frontmatter.date).toLocaleDateString(
    undefined,
    { month: "long", day: "numeric", year: "numeric" },
  )
  return (
    &amp;lt;div
      style={{
        display: `flex`,
        flexDirection: `column`,
        width: `1200px`,
        height: `630px`,
        backgroundColor: "black",
        border: "solid 15px #e5e02d",
        borderRadius: "25px",
        padding: "3em 1.5em",
        fontFamily: "BlinkMacSystemFont",
      }}
    &amp;gt;
      &amp;lt;h1 style={{ color: "#e5e02d", fontSize: "4em" }}&amp;gt;
        {node.frontmatter.title}
      &amp;lt;/h1&amp;gt;
      &amp;lt;h2 style={{ color: "#e5e02d", fontSize: "3em" }}&amp;gt;
        {node.frontmatter.description}
      &amp;lt;/h2&amp;gt;
      &amp;lt;div
        style={{
          display: "flex",
          borderTop: "3em solid #e5e02d",
          height: 0,
          width: "75%",
        }}
      &amp;gt;
        &amp;lt;h2
          style={{
            color: "black",
            position: "relative",
            bottom: "1.75em",
            marginLeft: ".5em",
            fontSize: "2em",
          }}
        &amp;gt;
          Posted on {postedDate}
        &amp;lt;/h2&amp;gt;
        &amp;lt;div
          style={{
            borderTop: "5em solid black",
            width: "5em",
            height: "5em",
            transform: "rotate(45deg)",
            position: "absolute",
            top: "-40px",
            left: "800px",
          }}
        &amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div
        style={{
          display: "flex",
          margin: "1em",
          position: "absolute",
          bottom: 0,
          right: 0,
          borderBottom: "2px solid #e5e02d",
        }}
      &amp;gt;
        &amp;lt;h2
          style={{
            color: "#e5e02d",
            alignItems: "flex-end",
            fontSize: "2em",
          }}
        &amp;gt;
          jvarness.blog
        &amp;lt;/h2&amp;gt;
        &amp;lt;img
          src="https://jvarness.blog/images/myself.jpeg"
          width={128}
          height={128}
          style={{
            borderRadius: "50%",
            margin: "1em",
            border: "solid 5px #e5e02d",
          }}
        /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here, it’s a little different from my example code in the OG Playground, but the key differences are mainly that it’s templated using the &lt;code&gt;frontmatter&lt;/code&gt; contained within all my blog posts. Other than that, it’s pretty much exactly what I put in the playground.&lt;/p&gt;

&lt;p&gt;One thing that is important to note here as well: you may notice that for the whole component I’m using a font style &lt;code&gt;fontFamily: "BlinkMacSystemFont"&lt;/code&gt;. In order to get a custom font into the plugin to resolve correctly, you’ll need to download the fonts you want to use. I was abel to find these fonts in &lt;a href="https://github.com/aliifam/BlinkMacSystemFont" rel="noopener noreferrer"&gt;this github repo&lt;/a&gt; and I was able to get it in &lt;code&gt;.otf&lt;/code&gt; format. I’m not sure if that matters or not, but the author of the satorare plugin was using &lt;code&gt;.otf&lt;/code&gt; in their example, so that’s what I did.&lt;/p&gt;

&lt;p&gt;Anyway, now that I’ve got the fonts I wanted to use &lt;em&gt;and&lt;/em&gt; I’ve got the component created that I wanted to use, it’s time to modify my&lt;code&gt;gatsby-config.js&lt;/code&gt; with the correct configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resolve: `gatsby-plugin-satorare`,
options: {
  path: `${__dirname}/src/components/social-image-card.js`,
  fonts: [
    {
      name: "BlinkMacSystemFont",
      path: `${__dirname}/content/assets/BlinkMacSystemFont.otf`,
    },
  ],
  target_nodes: ["MarkdownRemark"],
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that this is configured, the plugin, at build time, will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load the font(s) you want to use&lt;/li&gt;
&lt;li&gt;Load up all the node types contained in the &lt;code&gt;target_nodes&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Call the &lt;code&gt;social-image-card.js&lt;/code&gt; function for each of the nodes, which will then create images for the pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect. We’re almost done! Now that we have the images generating, now we need to actually start using them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actually Using the Images
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gatsby-plugin-satorare&lt;/code&gt; will create new schema within the GraphQL store that Gatsby uses to generate your site for each node type that you target. In this case, it generated a &lt;code&gt;markdownRemarkOgImage&lt;/code&gt; type in GraphQL that we can use to reference the location of each image. We are able to do this using the IDs of each blog post.&lt;/p&gt;

&lt;p&gt;For my blog posts, this was what the query used to look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const pageQuery = graphql`
  query BlogPostBySlug($id: String!) {
    markdownRemark(id: { eq: $id }) {
      excerpt(pruneLength: 160)
      html
      frontmatter {
        title
        date(formatString: "MMMM DD, YYYY")
        description
      }
      timeToRead
    }
  }
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be able to get the image data, I am now able to add a small snippet below the &lt;code&gt;markdownRemark&lt;/code&gt; query block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const pageQuery = graphql`
  query BlogPostBySlug($id: String!) {
    markdownRemark(id: { eq: $id }) {
      /* ... */
    }
    markdownRemarkOgImage(parent: { id: { eq: $id } }) {
      attributes {
        publicURL
      }
    }
  }
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when my blog posts render, the &lt;code&gt;data&lt;/code&gt; prop will have the &lt;code&gt;publicURL&lt;/code&gt; that can be used for the image!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const BlogPostTemplate = ({ data, pageContext }) =&amp;gt; {
  const { publicURL } = data.markdownRemarkOgImage.attributes
  // the rest of the code...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m using the images mainly in a &lt;code&gt;Helmet&lt;/code&gt; to be able to set the appropriate meta tags for these to show up on social media. If you are ever unsure of whether or not you’re using the right tags for this, I was able to use &lt;a href="https://socialsharepreview.com/" rel="noopener noreferrer"&gt;socialsharepreview&lt;/a&gt; to test them.&lt;/p&gt;

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

&lt;p&gt;Well now my blog looks a little more professional! I’m pretty happy with the way they turned out, and now hopefully social card links will look a little nicer than they used to! Thanks for reading if you made it this far, and let me know on DEV or LinkedIn if you tried this out at all and if it was helpful to you!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gatsby</category>
    </item>
    <item>
      <title>Creating a Radio Using HTML Canvases</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Sun, 20 Dec 2020 20:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/creating-a-radio-using-html-canvases-5f9j</link>
      <guid>https://dev.to/jvarness/creating-a-radio-using-html-canvases-5f9j</guid>
      <description>&lt;p&gt;Hey everyone! It’s been a solid month since my last post, but I’m back again, and this time I want to focus on finishing up that crappy little radio we made last time. For context, &lt;a href="https://ugly-kk-radio.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt; is what I left off with from &lt;a href="https://dev.to/html5-acnh-radio"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This little project started out as a submission for a programming competition, where I had to use 32 lines of code to make… Something, anything. But now that the competition is over, I can make this little project of mine whole with more code, specifically with CSS to draw a little radio on the screen, and some more JavaScript to make this project a little more robust than it is.&lt;/p&gt;

&lt;p&gt;But before we add play and pause functionality, we need to actually render something that resembles a radio. While it might not actually be a radio, I’m going to try to render something that looks like ACNH’s Tape Deck, because I like the way it looks.&lt;/p&gt;

&lt;h1&gt;
  
  
  Drawing a Radio
&lt;/h1&gt;

&lt;p&gt;First, I need to draw a radio. Most people would likely just… Draw one in Paint, Gimp, or their other favorite image manipulation program. However, this is a coding blog, and drawing a .png file doesn’t require writing any code, so instead we’re going to use a HTML &lt;a href="https://www.w3schools.com/html/html5_canvas.asp" rel="noopener noreferrer"&gt;&lt;code&gt;canvas&lt;/code&gt; element&lt;/a&gt;, which are really cool little elements you can use to draw things with using JavaScript.&lt;/p&gt;

&lt;p&gt;This was pretty tough for me to do because I didn’t fully know what methods were available to me in order to be able to draw the radio. I mostly needed to be able to draw shapes, but for the face of the radio I also wanted it to have some textures. I decided to go ahead and start with a box for the body of the radio. In order to do this I need a &lt;code&gt;canvas&lt;/code&gt;:&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;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"500px"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"300px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy. Now, I want to draw a box representing the body of the radio. In order to do that, I have to get the 2-dimensional context from the &lt;code&gt;canvas&lt;/code&gt; and start drawing shapes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;radio&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;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ddd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code gets a little bit boring from here. It’s mostly repeating setting the &lt;code&gt;fillStyle&lt;/code&gt; property and calling &lt;code&gt;fillRect&lt;/code&gt; to draw most of the body. I also drew a couple of circles by calling the &lt;code&gt;arc&lt;/code&gt; function to create a tape deck looking box, but the circle-drawing code is a little different. &lt;code&gt;fillRect&lt;/code&gt; draws rectangles and fills them in with a pattern or solid color, whereas arcs can be drawn differently depending on whether or not you call &lt;code&gt;fill&lt;/code&gt; or &lt;code&gt;stroke&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#aaa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ddd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#aaa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;170&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ddd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;170&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;210&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will draw gray circles below much lighter-gray circles. Using &lt;code&gt;fill&lt;/code&gt; here will create a circle filled in with a particular color based on what &lt;code&gt;fillStyle&lt;/code&gt; is set to. &lt;code&gt;stroke&lt;/code&gt;, however, has a different effect. Rather than just drawing a circle of the specified color, it draws a circle with a black outline.&lt;/p&gt;

&lt;p&gt;I wanted the stereo of the radio to have a textured look, but I didn’t want to repeat a ton of code to write little lines, so what I did is I created a tiny little image with the texture I wanted, and used the context’s &lt;code&gt;createPattern&lt;/code&gt; function to create a pattern with that image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;radioTexture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;radioTexture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;radio_texture.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;radioTexture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;radioPattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radioTexture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;repeat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;radioPattern&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This made it really easy to create the texture I wanted without drawing it all using the canvas.&lt;/p&gt;

&lt;p&gt;After a little added CSS, I’m starting to like what I created. The radio is a little less ugly now, and it… Actually looks like a radio!&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/7a184fe73eaffc7aac4d75edf6be9928/1ddef/radio.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F7a184fe73eaffc7aac4d75edf6be9928%2Ffcda8%2Fradio.png" title="A digital-looking screenshot of something that resembles a 90s tape deck." alt="A digital-looking screenshot of something that resembles a 90s tape deck." width="590" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I still have a lot more that I want to add to this, but this is a pretty good start for something looking a little bit better. To see the product as it is now, you can &lt;a href="https://less-ugly-kk.vercel.app/" rel="noopener noreferrer"&gt;click here&lt;/a&gt;. I think at some point in 2021 we’ll start to add more functionality, and hopefully by… 2025 we’ll have a finished product!&lt;/p&gt;

&lt;p&gt;This is probably going to be the last blog post I make this year, so I just wanted to say that if you enjoyed any of my posts that I’ve written this year, first off thanks so much for reading, and let me know what your favorite one was and why on social media!&lt;/p&gt;

&lt;p&gt;Happy Holidays and a Happy New Year to you and your family and friends! I’ll see you all again in 2021!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Building an ACNH Radio using HTML5 Audio Tags</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Sun, 08 Nov 2020 09:14:00 +0000</pubDate>
      <link>https://dev.to/jvarness/building-an-acnh-radio-using-html5-audio-tags-5mc</link>
      <guid>https://dev.to/jvarness/building-an-acnh-radio-using-html5-audio-tags-5mc</guid>
      <description>&lt;p&gt;&lt;a href="https://cerner.com" rel="noopener noreferrer"&gt;Cerner&lt;/a&gt;, the company I’m currently employed at, holds an annual hackathon called 2^5, where every day for 32 days, you can make 1 submission of code that is 32 lines long or less. I’ve blogged about this previously on dev.to, and you can check out the post &lt;a href="https://dev.to/jvarness/32-lines-of-code-4bgc"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ve been a participant for 4 years, and it always surprises me how much folks are able to do using only 32 lines of code. This year was one of my favorite years to participate because I themed all of my submissions around Animal Crossing: New Horizons. Like millions of other Nintendo Switch gamers out there, ACNH became daily therapy as I caught bugs and fish, dug up fossils, and built an island full of really awesome villagers (the best overall being &lt;a href="https://nookipedia.com/wiki/Cherry" rel="noopener noreferrer"&gt;Cherry&lt;/a&gt;, as I’m sure everyone who has ever had her as a villager would agree).&lt;/p&gt;

&lt;p&gt;What excited me even more was to find a &lt;a href="http://acnhapi.com/" rel="noopener noreferrer"&gt;community-supported REST API&lt;/a&gt; for the new game that would allow you to query for &lt;em&gt;a lot&lt;/em&gt; of in-game items and get information about those items in the form of a JSON body, and almost every submission for 2^5 that I made &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2020" rel="noopener noreferrer"&gt;this year&lt;/a&gt; revolved around this free API.&lt;/p&gt;

&lt;p&gt;There’s one submission that I made though that… Bothers me. A lot. I’ve thought about it non-stop since I submitted it, not for any reason other than the fact that it is visually one of the &lt;em&gt;ugliest&lt;/em&gt; things I’ve ever concocted. That submission is the &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/blob/master/2020/JS/kk/index.html" rel="noopener noreferrer"&gt;radio that plays K.K. Slider songs&lt;/a&gt;. For brevity, I’ve deployed this file to Vercel &lt;a href="https://ugly-kk-radio.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt; so that you can see what it does.&lt;/p&gt;

&lt;p&gt;As you can see, this is really &lt;em&gt;really&lt;/em&gt; not visually appealing in any sense of the word. The JavaScript that was needed to make this work correctly made the file so large that there wasn’t really enough time leftover to make it pretty…&lt;/p&gt;

&lt;p&gt;I’m working on making it prettier right now, so for now, I’ll focus on what the &lt;code&gt;audio&lt;/code&gt; tag in HTML5 can do for you, and how I used it to make a little mvp of a radio!&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving Music
&lt;/h2&gt;

&lt;p&gt;First thing we need to discuss is: how are we going to be retrieving the music we want to play? Well first I needed to go retrieve a song to play. The ACNH API has a &lt;a href="http://acnhapi.com/doc#tag/Songs" rel="noopener noreferrer"&gt;Songs endpoint&lt;/a&gt; that makes this easy. Since I’m buildling a radio, I just want to go get random songs to play, so I’ll first start by generating a random integer in JavaScript between 1 and 95:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;94&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of those quirky things about JavaScript that I really dislike: unlike other modern languages that can actually generate a random integer, us JavaScript developers have to use a combination of &lt;code&gt;Math.random&lt;/code&gt; (which generates a random decimal number between 0.0 and 1.0) and &lt;code&gt;Math.floor&lt;/code&gt; (which will round a number down to it’s nearest whole number value, so numbers like 3.9, 3.7, and 3.0000001 all become 3). My intention here is to generate a random number between 1 and 95, because the ANCH API uses positive integers for the IDs, and currently the only way to get songs from the API is to use ID numbers within that range as query parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`https://acnhapi.com/v1/songs/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;94&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;setSong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m not using NPM for this project, so just using &lt;code&gt;XMLHttpRequest&lt;/code&gt; works for my needs. Now… What is that &lt;code&gt;setSong&lt;/code&gt; and what does it do? Well, I use that to set some attributes on an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio" rel="noopener noreferrer"&gt;HTML5 &lt;code&gt;audio&lt;/code&gt; tag&lt;/a&gt;. Using this tag will help me answer the next conundrum:&lt;/p&gt;

&lt;h2&gt;
  
  
  Playing Music
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;audio&lt;/code&gt; tag, when provided with a music &lt;code&gt;source&lt;/code&gt;, can play audio media straight from a browser once the browser has loaded the audio! So we can take our response from the API call, extract the URL of the MP3 from it, and begin to play it:&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;audio&lt;/span&gt; &lt;span class="na"&gt;autoplay&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"audio/mpeg"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;Looks like your browser doesn't support audio tags :(
&lt;span class="nt"&gt;&amp;lt;/audio&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setSong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name-USen&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;source&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;music_uri&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;audio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will set the &lt;code&gt;src&lt;/code&gt; of the &lt;code&gt;source&lt;/code&gt; tag, which will then allow the &lt;code&gt;audio&lt;/code&gt; tag to start playing music, once it’s told to start playing. Before I go any further, I want to address how this code actually plays music, and why if you’re on a Chrome-based browser, the &lt;code&gt;autoplay&lt;/code&gt; attribute likely isn’t causing the song to auto-play like you would expect:&lt;/p&gt;

&lt;p&gt;From the Mozilla docs I linked above, the &lt;code&gt;audio&lt;/code&gt; tag has many attributes. The two main ones I want to focus on are &lt;code&gt;autoplay&lt;/code&gt; and &lt;code&gt;controls&lt;/code&gt;. Many browsers will honor &lt;code&gt;autoplay&lt;/code&gt; if the &lt;code&gt;controls&lt;/code&gt; attribute is included here, the reason being that &lt;code&gt;controls&lt;/code&gt; asks the browser to supply music controls for the media. For this project, I don’t want to render the default controls, and I want it to still &lt;code&gt;autoplay&lt;/code&gt; where available, which is why I left it in.&lt;/p&gt;

&lt;p&gt;However, Chrome refuses to &lt;code&gt;autoplay&lt;/code&gt; any media without controls being present to play/pause said media. Because of this, I had to introduce something into the UI that would allow it to play the media based on a user-action, so I just added an &lt;code&gt;onClick&lt;/code&gt; handler on the &lt;code&gt;body&lt;/code&gt; tag, the entirety of which ends up looking like this:&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;body&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"document.querySelector('audio').load();"&lt;/span&gt; &lt;span class="na"&gt;onload=&lt;/span&gt;&lt;span class="s"&gt;"loadNextSong()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Click here to start playing music.&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;audio&lt;/span&gt; &lt;span class="na"&gt;autoplay&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"audio/mpeg"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;Looks like your browser doesn't support audio tags :(
  &lt;span class="nt"&gt;&amp;lt;/audio&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when the page loads, the user is prompted to click somewhere in order to start playing music. Now, we’re building a radio, so when the first song we loaded stops, how do we load the next one?&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuously Playing Music
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;audio&lt;/code&gt; tag comes with very convenient event handlers that we can take advantage of. The main one that we’ll be able to take advantage of for our radio is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event" rel="noopener noreferrer"&gt;&lt;code&gt;ended&lt;/code&gt;&lt;/a&gt; event. So far, the JavaScript we’ve written looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setSong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name-USen&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;source&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;music_uri&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;audio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;load&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;loadNextSong&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Loading...&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;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`https://acnhapi.com/v1/songs/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;94&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;setSong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&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="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have functions for retrieving the next song, and loading it into our web page. However, this code will stop playing after the first randomly selected song. We can’t have it stop. What would K.K. Slider think of us if that happened?&lt;/p&gt;

&lt;p&gt;Luckily, we can just load the next song when the audio tag has ended the playing of media. We can do this by adding an event handler for the &lt;code&gt;ended&lt;/code&gt; event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;audio&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ended&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loadNextSong&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the song stops playing, we’ll query up another song, set all the appropriate tags, and then &lt;code&gt;document.querySelector('audio').load()&lt;/code&gt; will play the next song for us! Because we added &lt;code&gt;autoplay&lt;/code&gt; to the audio tag, and the user had to click on the body of the page in order to start playing, songs will continue to play even in Chrome until the browser is closed!&lt;/p&gt;

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

&lt;p&gt;This is not a bad start for an ACNH radio, but the internet deserves better! So far, I don’t have a way to turn the radio off once it’s on, and it… Really doesn’t look so much like a radio.&lt;/p&gt;

&lt;p&gt;Stay tuned for an upcoming post where I use some CSS magic to turn this blob of text on a screen into something we can all be proud of. Until then, I hope you liked learning a little bit about how you could use the &lt;code&gt;audio&lt;/code&gt; tag! If you have any questions or feedback for me, links to my social media can be found on my profile. Thanks for reading, and have a good one!&lt;/p&gt;

</description>
      <category>html</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Adding serverless APIs to Gatsby projects in Vercel</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Sat, 31 Oct 2020 15:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/adding-serverless-apis-to-gatsby-projects-in-vercel-i2a</link>
      <guid>https://dev.to/jvarness/adding-serverless-apis-to-gatsby-projects-in-vercel-i2a</guid>
      <description>&lt;p&gt;Hey everyone! It’s been a solid two weeks since I’ve actually written a blog. I’ve been feeling really under the weather, so I’ve been mostly taking the last few weeks easy (don’t worry, it wasn’t/isn’t COVID). That, and Pokemon Crown Tundra got released, so I’ve been playing a lot of that lately, but it feels nice to be back to writing some blogs!&lt;/p&gt;

&lt;p&gt;In the blog I wrote about &lt;a href="https://jvarness.blog/how-this-site-was-made" rel="noopener noreferrer"&gt;how I created my blog&lt;/a&gt;, I briefly mentioned that one of the reasons that I didn’t need to use Next.js for this site was because of the fact that it offered more functionality than I needed. All the pages on this site are built statically, and Next.js can do that too, but it also has great support for &lt;a href="https://nextjs.org/docs/api-routes/introduction" rel="noopener noreferrer"&gt;dynamic routes and APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m not convinced that this point that I’ll ever need dynamic routing built into this site since it’s using Gatsby. However, I might want to create APIs later for mailing lists, forms, etc. If I ever do need those APIs, Vercel actually makes it really easy to add APIs to any project.&lt;/p&gt;

&lt;p&gt;Originally this post was going to be about how easy making microservice APIs is using &lt;a href="https://github.com/vercel/micro" rel="noopener noreferrer"&gt;micro&lt;/a&gt;, but then I discovered that micro was designed to be ran within a container, and that Vercel has better support for adding APIs to any Node project using it’s &lt;a href="https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-request-and-response-objects" rel="noopener noreferrer"&gt;Serverless Helper Functions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an API
&lt;/h2&gt;

&lt;p&gt;Adding serverless APIs to Vercel projects is dead simple. You can review the link above and find some instructions. What I’ve done on this site is I’ve deployed the example shown in the link to a route on my website at &lt;a href="https://jvarness.blog/api/examples/hello-world" rel="noopener noreferrer"&gt;&lt;code&gt;api/examples/hello-world&lt;/code&gt;&lt;/a&gt;. For posterity, the code just looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a fairly straight-forward function: it accepts two objects, one representing the &lt;code&gt;req&lt;/code&gt;uest, which contains all the query parameters and any applicable bodies, and then an object we can use to send the &lt;code&gt;resp&lt;/code&gt;onse with.&lt;/p&gt;

&lt;p&gt;I added this route by simply creating an &lt;code&gt;api&lt;/code&gt; folder at the root of my project. Vercel will build out serverless API routes using the file structure defined within the &lt;code&gt;api&lt;/code&gt; folder, and will serve any &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.go&lt;/code&gt;, &lt;code&gt;.py&lt;/code&gt;, or &lt;code&gt;.rb&lt;/code&gt; files defined within as serverless lambda functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consuming in Gatsby
&lt;/h2&gt;

&lt;p&gt;I was really hoping to consume the API directly from this blog post, but I’m not using &lt;a href="https://github.com/mdx-js/mdx" rel="noopener noreferrer"&gt;mdx&lt;/a&gt; for my posts quite yet, and injecting JavaScript in-line on a markdown file didn’t really seem like a very &lt;em&gt;safe&lt;/em&gt; thing to try and do, nor did I think it was feasible. SO, instead, I created an example page of how a Gatsby page might consume a serverless function.&lt;/p&gt;

&lt;p&gt;You can view the demo &lt;a href="https://jvarness.blog/examples/api-example" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but I’ll talk more about the code here. You might consider opening the demo page up on another tab.&lt;/p&gt;

&lt;p&gt;In order to get the query parameters, Gatsby passes in &lt;a href="https://www.gatsbyjs.com/docs/location-data-from-props/" rel="noopener noreferrer"&gt;&lt;code&gt;location&lt;/code&gt; data&lt;/a&gt; to each of it’s pages. We can use this, along with the &lt;a href="https://www.gatsbyjs.com/docs/recipes/querying-data/#querying-data-client-side-with-fetch" rel="noopener noreferrer"&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/a&gt; API to grab the query params, can call our serverless function with the parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&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="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../components/layout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SEO&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../components/seo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;queryString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query-string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;queryString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;search&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;greeting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/examples/hello-world?name=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;greet&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;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SEO&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hero is-white is-large"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hero-body"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"title"&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;greeting&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;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        If you stumbled upon this page not knowing what it was, go &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/adding-serverless-apis-to-gatsby-projects-in-vercel`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; here.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Layout&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;We’re able to use &lt;code&gt;fetch&lt;/code&gt; to call an API using query parameters that were read from &lt;code&gt;location&lt;/code&gt; data, and then render that data client-side once the server responds! Neato!&lt;/p&gt;

&lt;p&gt;The one thing you might notice when loading the page is that while the page rendering is pretty quick, there’s a bit of a delay in loading the actual information from the serverless function created by Vercel, hence our page says “Loading…” first before getting the actual greeting. I will say that this is one thing that Next.js does pretty well that Gatsby does not: all pages in Gatsby are static, whereas Next.js can actually create &lt;em&gt;lambdas&lt;/em&gt; of pages, so the loading and rendering of the data is handled server-side. If we were using Next.js, we could use it’s &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering" rel="noopener noreferrer"&gt;&lt;code&gt;getServerSideProps&lt;/code&gt;&lt;/a&gt; API to render everything server-side so that the client doesn’t have to load any data itself. No need for loading indicators.&lt;/p&gt;

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

&lt;p&gt;Hopefully you’ve found some of this information useful! As always, links to my social media are located below if you want to ask questions about this post or if you want to suggest a future post. Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gatsby</category>
      <category>vercel</category>
    </item>
    <item>
      <title>Trying Out One-Line Dark Mode Tricks</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Tue, 13 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/trying-out-one-line-dark-mode-tricks-a97</link>
      <guid>https://dev.to/jvarness/trying-out-one-line-dark-mode-tricks-a97</guid>
      <description>&lt;p&gt;I’ve read a few articles on the internet about how you can implement dark mode on your website in one line of CSS. Honestly, it’s a really nifty trick. For reference, here are the articles I have seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/dip15739/dark-mode-with-only-1-css-property-17fl"&gt;Dark Mode with only 1 CSS PROPERTY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/akhilarjun/one-line-dark-mode-using-css-24li"&gt;One line - Dark Mode using CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ekaterina_vu/dark-mode-with-one-line-of-code-4lkm"&gt;Dark Mode With One Line Of Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a neat trick, really it is. I’m a fan, and it works pretty well… For some websites. Since I now have a website, I thought to myself “self, why don’t you also include some kind of toggle for dark mode on your website using this trick!“.&lt;/p&gt;

&lt;p&gt;So I tried it… And uh… Well, let’s get into why I don’t really like the idea very much.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying with 1 CSS Style
&lt;/h2&gt;

&lt;p&gt;Let’s just start with figuring out what this website looks like if we apply this filter style on my website in Chrome dev tools. Adding this CSS property on the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element yields interesting results for the site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;invert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;hue-rotate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;180&lt;/span&gt;&lt;span class="nt"&gt;deg&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All the colors are inverted, but it turns out the yellow color I chose doesn’t look all that great when it’s inverted:&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/8f6d0135ca3708c17287af4772259998/e3b18/dark-mode-initial.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F8f6d0135ca3708c17287af4772259998%2Fe3b18%2Fdark-mode-initial.png" title="My website after inverting the colors and a 180-degree hue rotation" alt="My website after inverting the colors and a 180-degree hue rotation" width="439" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whites turn black, the blacks turn white, and the yellow turns… Brown? Ew… Well, what if I just tried it without the &lt;code&gt;hue-rotate&lt;/code&gt; style and just had &lt;code&gt;filter: invert(1)&lt;/code&gt;? The result is a little bit better:&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/945668aa05f59a3d0a1b85a7d386155f/e3b18/blue-dark-mode.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F945668aa05f59a3d0a1b85a7d386155f%2Fe3b18%2Fblue-dark-mode.png" title="The yellows on the site turn blue instead" alt="The yellows on the site turn blue instead" width="439" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/00825432b79e64ac451f834ba755c477/e3b18/code-highlighting.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F00825432b79e64ac451f834ba755c477%2Fe3b18%2Fcode-highlighting.png" title="The code highlighting looks pretty good" alt="The code highlighting looks pretty good" width="439" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This looks a little bit better, even some of the posts don’t look too bad: the code snippets and inline highlighting don’t look all that bad. However, there are other subtle elements of the site that don’t really look right. The footer, for example, has a really poor contrast ratio between the links I have there and the now white background:&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/4ad97793a76b507a7d138206e2f99f68/3d026/footer-with-blue.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F4ad97793a76b507a7d138206e2f99f68%2F3d026%2Ffooter-with-blue.png" title="The footer with just invert(1)" alt="The footer with just invert(1)" width="429" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My fear here is that users who have colorblindness might not be able to easily see some of these links. The icons look pretty good inverted though, so what I can do is make the links the same color as the icons, and that’ll solve that problem pretty easily, because they’ll turn the same blue as the icons:&lt;/p&gt;

&lt;p&gt;&lt;a href="/static/626a7a6bd0f8b03c917187ea0acc8d66/71ce0/blue-links.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fjvarness.blog%2Fstatic%2F626a7a6bd0f8b03c917187ea0acc8d66%2F71ce0%2Fblue-links.png" title="Links are as blue as the icons on the footer" alt="Links are as blue as the icons on the footer" width="463" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So this isn’t too bad still… But I’m not sure I really like the blue color still. I picked that yellow because I like it. I want it to stay that way. Plus, this is just a style: I still need to figure out a way to turn it off and on again, which will require some JavaScript on my part.&lt;/p&gt;

&lt;p&gt;I’ll eventually get a dark mode added to my website, but I don’t think I’ll be using this method for it. I think for other websites that have simpler color schemes this might be a great technique to use! But for my website, it’s just not working the way I want it to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Examples
&lt;/h2&gt;

&lt;p&gt;Other websites have great examples of how their dark mode is implemented. One notable one is Dan Abramov’s site &lt;a href="https://overreacted.io/" rel="noopener noreferrer"&gt;overreacted.io&lt;/a&gt;. Dan is the creator of React, and this blog was created using Gatsby! You can check out the source code &lt;a href="https://github.com/gaearon/overreacted.io" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dan’s implementation is very elegant: the base color scheme for all the text and content just looks visually appealing regardless of whether or not the background is light or dark. The background becomes a different color based on classes added to the &lt;code&gt;body&lt;/code&gt; of the page. Dan also has some code in here that will persist the selected theme between sessions so that the next time the site is visited it’s using the same theme.&lt;/p&gt;

&lt;p&gt;The Gatsby community seems to agree that this is a pretty good implementation! Someone from the community decided to create a plugin that implements much of the code that Dan uses to persist the theme state and trigger updates to the theme. Source code for that plugin can be found &lt;a href="https://github.com/insin/gatsby-plugin-dark-mode" rel="noopener noreferrer"&gt;here&lt;/a&gt;. For anyone looking to implement similar themes or triggers, this is a good starting point!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;So what does this teach us about dark mode? You can certainly use a CSS style like &lt;code&gt;filter&lt;/code&gt; to invert all of the colors on your website to achieve the desired effect, but as the color scheme I’m using can prove, it can be a little difficult to implement it using &lt;code&gt;filter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a later blog post, if I’m ever going to be able to figure out how to make this work for my site, I’ll discuss how I overcame all these different challenges, and how I was able to actually implement it.&lt;/p&gt;

</description>
      <category>css</category>
    </item>
    <item>
      <title>How I made jvarness.blog</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Wed, 07 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/how-i-made-jvarness-blog-jna</link>
      <guid>https://dev.to/jvarness/how-i-made-jvarness-blog-jna</guid>
      <description>&lt;p&gt;A colleague of mine reached out to me and asked if I could spend a little bit of time blogging about how I created this blog. I told that colleague I would soon, so hopefully they’ll enjoy this.&lt;/p&gt;

&lt;p&gt;Aside from being asked by a colleague: I want to talk about what my needs &lt;em&gt;currently&lt;/em&gt; are for the blog, the technologies I’m using to create the blog, and why I chose those technologies over competitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;del&gt;Bear&lt;/del&gt; Bare Necessities
&lt;/h2&gt;

&lt;p&gt;First things first: this is a blog. It’s a website, not an app, and I knew I didn’t need or want to maintain any kind of app. That helped narrow down my tech search. I wanted this to just be a website that I could post my thoughts and ideas and projects to.&lt;/p&gt;

&lt;p&gt;There were things I could have done that would have made the site much more complicated to setup initially, but I could have added more features over time: I could have created some kind of Ruby on Rails application and served my content via a CMS such as &lt;a href="https://strapi.io/" rel="noopener noreferrer"&gt;Strapi&lt;/a&gt;, but there were two major concerns that I had about that:&lt;/p&gt;

&lt;p&gt;First thing is that I would have needed to setup and deploy both the website in Rails, as well as a Strapi instance somewhere like &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;Digital Ocean&lt;/a&gt; or on &lt;a href="https://www.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt;, but for something like a blog there are cheaper options.&lt;/p&gt;

&lt;p&gt;The second concern I would have had about that is performance: Rails screams, but only if you have the hardware an infrastructure to help it scale. I didn’t want to worry too much about performance with this, because in the end it’s &lt;em&gt;just a blog&lt;/em&gt;, and you could end up paying big with that kind of server side rendering architecture… Or really any kind of rendering for that matter.&lt;/p&gt;

&lt;p&gt;I knew that I could achieve better performance through static rendering and generation than I could if I hosted my content on a CMS and loaded that content in for each page hit, and because I know how to write JavaScript (and I like to write JavaScript code), it became pretty clear what I wanted to do: &lt;a href="https://jamstack.org/" rel="noopener noreferrer"&gt;JAMStack&lt;/a&gt; it!&lt;/p&gt;

&lt;h2&gt;
  
  
  JAMStack
&lt;/h2&gt;

&lt;p&gt;In the world of JAMStack, there are many technologies and companies that make it extremely simple to make a website. In fact, on the JAMStack site, there are a ton of options &lt;a href="https://jamstack.org/generators/" rel="noopener noreferrer"&gt;listed here&lt;/a&gt; that can help you achieve what you’re wanting to do. I’m not going to talk about all of the options that you have, but I will talk about a few that I did consider:&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; is a React framework for building websites, created by &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; (formerly Zeit), with the aim of being extremely flexible: site pages can be generated statically, they can render dynamically using microservice APIs, it’s easy to add your own microservices into the same code base, and code-splitting is built-in, meaning that your JavaScript isn’t bundled into one big blob, but rather just the JavaScript that each individual page needs.&lt;/p&gt;

&lt;p&gt;For pages that are dynamically rendered, Next.js creates a lambda function, which is a huge plus for anyone who wants to create dynamically rendered pages: lambda functions are a great way to keep the costs of deploying a website down, and it doesn’t require a server to be constantly running.&lt;/p&gt;

&lt;p&gt;I’m a huge fan of using Next.js to build applications and websites. I would recommend it to a lot of people. However, I didn’t really feel as if I needed &lt;em&gt;all&lt;/em&gt; of the power that Next.js had to offer: I don’t have a need to create any microservices, and if I did I can always create and deploy those very easily. If I did feel as if I needed them though, Next.js would be what I would reach for.&lt;/p&gt;

&lt;p&gt;One other thing I don’t find particularly convenient about Next.js is the ability to create posts using Markdown: Kendall Strautman made a blog that you can find &lt;a href="https://dev.to/tinacms/creating-a-markdown-blog-with-next-js-52hk"&gt;here&lt;/a&gt; on how to setup a Markdown blog using Next.js. I spent a good long while trying to get this to work with &lt;a href="https://www.netlifycms.org/" rel="noopener noreferrer"&gt;NetlifyCMS&lt;/a&gt;, but Next.js just isn’t elegant for this because I believe at it’s core it’s trying to solve a completely different use-case: quickly rendering pages through the use of microservice architectures. But like I said, I don’t really need those, I just want to write Markdown and get a site working.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nuxt.js
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;Nuxt&lt;/a&gt; is another JavaScript framework that looks to solve many of the same use-cases as Next, but instead of using React it uses Vue.&lt;/p&gt;

&lt;p&gt;I don’t really have more experience with Nuxt than I do with Next, but of the experience that I do have, I can tell you that Nuxt’s plugin system is pretty elegant. With Next, there tends to be a lot of webpack configuration you have to go through in order to get things exactly how you want them if you’re deviating from use-cases that Next tries to solve. In my opinion, Nuxt has a lot more intuitive configuration and plugin setup, and there are so many nice conventions in Nuxt that make organizing the source code very easy.&lt;/p&gt;

&lt;p&gt;For more complex websites, Nuxt is a great option for those who want more configurability in their site, or for those who just love Vue more than they love React. Nuxt really was a close second for this site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gatsby
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt; is considered to be the defacto static site generator for React developers by many in the React/JAMStack community. It’s primary goal is to utilize APIs to create static pages. It heavily utilizes GraphQL and plugins curated by the Gatsby community to query data sources and build a site. It’s also very easy to learn if you have a good understanding of React. In fact, much of the groundwork for this website was laid using the tutorial on Gatsby’s website, found &lt;a href="https://www.gatsbyjs.com/tutorial/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main difference between Nuxt/Next and Gatsby to me is that Gatsby makes it extremely easy to source information from files within a repository in order to build the content, whereas Nuxt/Next make it easy to create small services that can be used to dynamically render pages. To me, this was the simplest and easiest way to create a blog: I wrote posts in Markdown, and Gatsby turns it into a website!&lt;/p&gt;

&lt;p&gt;The one caveat about Gatsby, that I think I’m willing to compromise on at the moment, has to deal with build times. Next and Nuxt are both best tailored to load content from REST APIs, which means that your build times are only as long as it takes to build each lambda or static page that your site requires. You sacrifice a small portion of load times to have extremely fast builds.&lt;/p&gt;

&lt;p&gt;As of the publishing of this post, there are only a total of 4 blog posts, and as such, Gatsby’s build times are extremely quick. However, with my current implementation, Gatsby won’t be able to scale as I continue to add more and more posts. My builds will start to take longer because Gatsby will have to build &lt;em&gt;every single post&lt;/em&gt; as a new page.&lt;/p&gt;

&lt;p&gt;However, loading times for statically rendered sites are significantly faster than those backed by services. In this case, I’m willing to sacrifice slower builds to be able to host the same content and have that content be really fast to load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting
&lt;/h2&gt;

&lt;p&gt;There are about as many options for hosting as there are for actually generating your site. I already mentioned Digital Ocean and Heroku, but those fit different use-cases than what I was really needing. I didn’t want to have to manage an OS, or hardware resources, or whether or not I wanted my site to be scalable… I just wanted to deploy a website.&lt;/p&gt;

&lt;p&gt;There are a few platforms I’m aware of that make this extremely easy to do. I’ll discuss two of them that I didn’t use, and what I ultimately decided to utilize.&lt;/p&gt;

&lt;h3&gt;
  
  
  Surge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://surge.sh/" rel="noopener noreferrer"&gt;Surge&lt;/a&gt; is a platform you can use to deploy static sites quickly and easily. It offers a CLI that can be easily installed via NPM, and the free tier is extremely generous in terms of being able build as many projects into Surge as you want. It’s really easy to use.&lt;/p&gt;

&lt;p&gt;However, Surge is almost too simple: your website has to be built first in order to deploy it. The project has to be in a pre-built state before being published to the Surge network. This means that if you want to automate deployments when you push to a repo, you’ll need to setup some kind of continuous integration service to take care of getting the CLI and publishing for you. If you’re interested in Surge but you want automated deployments, there should be a guide in the docs on how to set it up with an old favorite of mine, &lt;a href="https://travis-ci.org/" rel="noopener noreferrer"&gt;Travis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sadly, I did not choose Surge for my deployments and hosting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Netlify
&lt;/h3&gt;

&lt;p&gt;Oh boy… I’m sure I’m going to get some flak for this… I’ll admit it: I’ve actually never tried using &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;. For those of you reading this who love Gatsby, you must think I’m crazy. You might be right.&lt;/p&gt;

&lt;p&gt;Netlify is a big favorite amongst many in the JAMStack community, and it’s not hard to understand why: Netlify deploys sites to a super fast CDN, and is capable of deploying static pages, as well as lambdas. It’s a really great choice for anyone who is creating a website with Nuxt, Next, Gatsby… Really, any static site generator.&lt;/p&gt;

&lt;p&gt;Netlify also has an easy-to-integrate CMS aptly named &lt;a href="https://www.netlifycms.org/" rel="noopener noreferrer"&gt;Netlify CMS&lt;/a&gt;. The way that Netlify CMS works is that the data is actually all hosted in GitLab or GitHub, and Netlify CMS will load posts from those sources. Then, when a post is edited or added, those updates will be pushed to the repository from Netlify CMS on your behalf, and can be stored as JSON, Markdown, whatever is supported.&lt;/p&gt;

&lt;p&gt;This is Gatsby’s strong suit: since the data that Gatsby uses to generate all of the pages is held within the repo itself, it’s possible to easily add Netlify CMS to any Gatsby site.&lt;/p&gt;

&lt;p&gt;Netlify, Netlify CMS, and Gatsby, would all be extremely attractive options if you wanted to create a website for practically no money down, and you wanted multiple people to be able to contribute to it, or if you wanted people who were not engineers to be able to contribute without having to understand Markdown or code. Couple that with things that developers care about, like Git integration and built-in site generation and deployments, and you have a match made in heaven.&lt;/p&gt;

&lt;p&gt;… Or at least for other people. Not necessarily for me. There’s another platform I’ve been using for quite some time now that I just can’t stop using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vercel/Zeit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; (Zeit) is a company that you may or may not have heard about: I don’t think they get nearly the amount of praise that Netlify does or the kind of attention that Netlify typically does, but they are just as good as Netlify for building and deploying sites. The company itself owns a lot of really neat &lt;a href="https://vercel.com/oss" rel="noopener noreferrer"&gt;open-source software&lt;/a&gt; that you may already be using, such as the Hyper terminal emulator, and they’re also the minds behind Next.js, Mongoose… My main point is that they do a lot of really neat stuff.&lt;/p&gt;

&lt;p&gt;There are so many great things about Vercel that make it an excellent platform for developers: a free pricing tier that allows you to deploy all kinds of projects is just the start. Actually, fun fact about Vercel: as of the writing of this article, ALL personal accounts are FREE, meaning you don’t have to pay anything to deploy your personal projects. Accounts only become paid if they are team accounts, where you want multiple contributors to join your project.&lt;/p&gt;

&lt;p&gt;Next are the different features: full integration with GitLab, GitHub, and Bitbucket, easy to use integrations to other sites through their integrations marketplace, but probably my favorite feature of all is the CLI.&lt;/p&gt;

&lt;p&gt;With the &lt;a href="https://vercel.com/docs/cli" rel="noopener noreferrer"&gt;Vercel CLI&lt;/a&gt;, it’s possible to take advantage of all the power Vercel has to offer right at your fingertips. You can buy a domain name, manage DNS records for your domains, deploy a node project straight to the Vercel platform (regardless of whether or not it’s stored in a Git repository), manage deployments… Literally anything you would normally want to manage through a web client, you can do on the command line. You never have to leave your development environment to manage your projects in production. Like Surge and Netlify, Vercel will also deploy your site with every push, can can create vanity URLs on it’s platform for every Git branch you create.&lt;/p&gt;

&lt;p&gt;For me, having used Vercel for many years, this wasn’t a difficult decision to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  That’s About All Folks
&lt;/h2&gt;

&lt;p&gt;And that’s all she wrote! These are the decisions that lead me to develop my website the way you’re currently experiencing it. Hopefully these insights and thoughts that I’ve expressed have perhaps inspired you to consider creating your own blog, or experimenting with creating any kind of static website. Like I said before: there’s not much risk involved with using these platforms. It’s very easy, and almost always free, to create and experiment with different technologies and ways of creating websites. If you have any questions, please reach out to me on social media! You can find links below. I’d be happy to answer your questions or hear your feedback. Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>My Gripes about C-Style for-loops</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Fri, 25 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/my-gripes-about-c-style-for-loops-jfj</link>
      <guid>https://dev.to/jvarness/my-gripes-about-c-style-for-loops-jfj</guid>
      <description>&lt;p&gt;One of the most useful (and often one of the most fundamental) concepts when learning to code is looping. Loops are all around us, in virtually every language we know, and even if your language of choice doesn’t include primitive loops, there is likely a way to achieve executing the same block of code a fixed number of times, or by implementing some kind of basic means of iterating.&lt;/p&gt;

&lt;p&gt;The first programming language that I ever wrote code in was Python, but the first programming language I really got a firm grasp on, and that I still use to this day, is Java.&lt;/p&gt;

&lt;p&gt;Over Java’s history, it’s evolved immensely: JDK 11 has introduced modules, which is another way of organizing a codebase, JDK 8 introduced lambda functions (a feature which existed in many other langauges including C# and JavaScript for some time), and JDK 5 was when the enhanced for-loop was introduced.&lt;/p&gt;

&lt;p&gt;JDK 5’s last update was over a decade ago, but regardless of how old it is, I can’t help but notice that sometimes people are continuing to use C-Style for-loops, and not only that, but I can find very heavy usage of C-Style loops in a lot of code bases in other languages as well, such as C#. I want to write this blog post as a caution to those who are continuing to use this loop, and provide reasons as to why whenever I see C-Style loops in a code review, I’ll &lt;em&gt;almost always&lt;/em&gt; ask someone to refactor it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stability
&lt;/h2&gt;

&lt;p&gt;My first big gripe about C-Style for-loops is that they are extremely prone to bugs. For every line of code you write within a C-Style for-loop, there could be an error in almost every line, and there can be potentially a number of bugs that are present before you even start talking about what’s in the loop. Let’s look at a simple example, printing numbers in an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s technically nothing wrong with this code. We created an array, looped over each of the elements in that array, and printed each number out to the console. However, this loop is prone to all kinds of bugs. This code works without defects or error IF and ONLY IF:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;i&lt;/code&gt; is not mutated within the loop, and nothing is stopping it from being manipulated either temporarily or permanently&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i&lt;/code&gt; is always incremented by 1 after each execution of the loop&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;&lt;/code&gt; condition doesn’t change&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i&lt;/code&gt;’s initial value does not change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these things changes for any reason, we run the risk of encountering &lt;code&gt;ArrayIndexOutOfBoundsException&lt;/code&gt;s,not looping over each element, or skipping elements within the array. For having the simple task of iterating over 5 numbers, this seems like a lot of risk to impose at runtime.&lt;/p&gt;

&lt;p&gt;We can mitigate all of these issues by using alternative methods to looping over this structure. Since JDK 5,developers have been able to take advantage of enhanced for-loops, also referred to as for-each loops (yet again another construct that’s always been available in C#).&lt;/p&gt;

&lt;p&gt;Using an enhanced for-loop, the code now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will iterate over the array, and on each invocation of the loop it will assign the a value to the variable &lt;code&gt;num&lt;/code&gt;, then we can use that number without having to access the array! This addresses all of the concerns we had about C-Style for-loops in terms of stability.&lt;/p&gt;

&lt;p&gt;Enhanced for-loops can be used with any data structure that implements Java’s &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html" rel="noopener noreferrer"&gt;&lt;code&gt;Iterable&lt;/code&gt;&lt;/a&gt;interface, and because the &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" rel="noopener noreferrer"&gt;&lt;code&gt;Collection&lt;/code&gt;&lt;/a&gt; interface extends &lt;code&gt;Iterable&lt;/code&gt;, we can use it for every &lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt; in our code.&lt;/p&gt;

&lt;p&gt;Speaking of &lt;code&gt;Collection&lt;/code&gt;s, let’s discuss my next big gripe:&lt;/p&gt;

&lt;h2&gt;
  
  
  Time Complexity
&lt;/h2&gt;

&lt;p&gt;Let’s start this discussion with another example. I have a &lt;code&gt;List&lt;/code&gt; that I’m iterating over and I want to print each element in the &lt;code&gt;List&lt;/code&gt;, and let’s start with a C-Style loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, same as before: nothing too fancy about this code, and it works fine. Now, let’s switch from using &lt;code&gt;ArrayList&lt;/code&gt; to &lt;code&gt;LinkedList&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the exact same output, and at face value the only real difference is the fact that we’re using a different implementation of the &lt;code&gt;List&lt;/code&gt; interface. However, that’s an &lt;em&gt;extremely crucial&lt;/em&gt; difference in this situation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ArrayList&lt;/code&gt; is what it sounds like: it’s an implementation of the &lt;code&gt;List&lt;/code&gt; interface that uses an array as it’s underlying structure. This means that extracting data out of the list can happen in constant time.&lt;/p&gt;

&lt;p&gt;However, &lt;code&gt;LinkedList&lt;/code&gt; is a linked data structure. With an &lt;code&gt;ArrayList&lt;/code&gt;, the compromise for performance happens when adding elements to the list: the array has to “grow” by creating a new array with a larger size than the current underlying array, and moving all the elements to that new reference, and then garbage collection will take care of the rest. &lt;code&gt;LinkedList&lt;/code&gt;s are really efficient during the population of the list because the structure can be created in such a way that growing the list can happen in constant time. However, this comes at a cost of accessing the data by index: each &lt;code&gt;.get&lt;/code&gt; call will yield an n^2 time complexity, n being the index you’re trying to access.&lt;/p&gt;

&lt;p&gt;Just by switching from &lt;code&gt;ArrayList&lt;/code&gt; to &lt;code&gt;LinkedList&lt;/code&gt;, we exponentially increased the time complexity of this code. However, enhanced for-loops can help mitigate this issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But why is this more beneficial in terms of time complexity? Remember: &lt;code&gt;List&lt;/code&gt;s are &lt;code&gt;Collection&lt;/code&gt;s which are &lt;code&gt;Iterable&lt;/code&gt;. Each implementation of a &lt;code&gt;List&lt;/code&gt; comes with a built-in &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html#iterator--" rel="noopener noreferrer"&gt;&lt;code&gt;Iterator&lt;/code&gt;&lt;/a&gt; which can be used to efficiently iterate over the list. Normally, &lt;code&gt;Iterator&lt;/code&gt;s are designed to be as efficient as possible. &lt;code&gt;Iterator&lt;/code&gt;s can be scoped to the class implementing them to allow them to have scope to the internal members of the data structure, which allows them to do things like access links within a &lt;code&gt;LinkedList&lt;/code&gt; directly so that the next link can be fetched without having to loop over them like most &lt;code&gt;.get&lt;/code&gt; operations would normally do.&lt;/p&gt;

&lt;p&gt;Why wouldn’t we just use &lt;code&gt;ArrayList&lt;/code&gt; everywhere if this was the case though? You can control whether or not your API uses &lt;code&gt;ArrayList&lt;/code&gt;, sure, but that won’t stop other engineers from using some other kind of implementation in theirs, so guard yourself against these types of caveats by using the right loops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives to Enhanced for-loops
&lt;/h2&gt;

&lt;p&gt;What are some other ways we could achieve the same kind of results without using for-loops? In JDK 8, Java was introduced to lambdas and&lt;code&gt;Stream&lt;/code&gt;s, which aim to vastly improve our code by allowing us to manipulate structures by passing function references to &lt;code&gt;Streams&lt;/code&gt; to perform work. We can write code like this to do the same kind of work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a lambda that just calls &lt;code&gt;System.out.println&lt;/code&gt; on a variable called &lt;code&gt;num&lt;/code&gt; that gets initialized to a new element in the &lt;code&gt;List&lt;/code&gt;on each invocation. We can also simplify this code even further with some syntactic sugar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apart from enhanced for-loops and lambdas, the only other thing I could recommend is using the actual &lt;code&gt;Iterator&lt;/code&gt; class in conjunction with a &lt;code&gt;while&lt;/code&gt; loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numIterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;iterator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numIterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNext&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numIterator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has less issues than a C-Style for-loop does, but it can still pose issues if &lt;code&gt;.next&lt;/code&gt; is called more than once within the &lt;code&gt;while&lt;/code&gt; block. Nevertheless, it’s just as efficient as an enhanced for-loop. If I remember correctly… I think Java bytecode compiles down in such a way that a while-loop with an &lt;code&gt;Iterator&lt;/code&gt; and an enhanced for-loop are equivalent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cases for C-Style
&lt;/h2&gt;

&lt;p&gt;So now that I’ve gone on and on about how you shouldn’t use a C-style for-loop, let’s talk about when you should actually use one.&lt;/p&gt;

&lt;p&gt;There might be some cases when you simply cannot use an enhanced for-loop, or where the other methods I outlined don’t make logical sense. Maybe you code has to execute a finite number of times, and it’s not based on a collection or data structure of any kind. Maybe it’s based on some count, or a requirement stating that something needs to be done X-times.&lt;/p&gt;

&lt;p&gt;I spoke about time complexity in this post, but truth be told enhanced for-loops are not the single most efficient loop there is. In cases involving the need to iterate over data, yes, enhanced for-loops are your best bet, but they come at a slight performance cost of needing to keep track of the state of the &lt;code&gt;Iterator&lt;/code&gt;, as well as the additional calls to get the info out of the &lt;code&gt;Iterator&lt;/code&gt;. For applications where performance, both in terms of memory and time consumption, it might not be wise to utilize &lt;code&gt;Iterator&lt;/code&gt;s or enhanced for-loops.&lt;/p&gt;

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

&lt;p&gt;Thanks for letting me air out my grievances about one of our oldest language constructs! If you enjoyed this post,I’d love to hear your feedback on Twitter or Dev! Be sure to check out my blog for other posts like this!&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why I love Bulma</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Wed, 23 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jvarness/why-i-love-bulma-5gdb</link>
      <guid>https://dev.to/jvarness/why-i-love-bulma-5gdb</guid>
      <description>&lt;p&gt;I’ve never been good at styling things. My new blog might be some evidence of that! 😁 But styling a website isn’t just about picking color schemes: fonts, spacing, icons, etc… There’s a lot to consider when all I really want to do is create a few pages that look decent.&lt;/p&gt;

&lt;p&gt;I’ve tried &lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt; before, which has been a staple of the internet for many years, and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt; has gained significant traction over the last few years, but my go-to library for my CSS needs has been &lt;a href="https://bulma.io/" rel="noopener noreferrer"&gt;Bulma&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think I discovered Bulma through Twitter. I think someone tweeted about it, and the more I looked into it the more interested I became. Hopefully just talking about some of the things I like about Bulma might spark more interest in it!&lt;/p&gt;

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

&lt;p&gt;Bulma has many components built into it that are very easy to setup, and are well documented! One big selling point that Bulma pushes is that it’s all in one CSS file. In the big world of programming, you can always take a bunch of different CSS files, and minify them into one file. The selling point here is mainly to emphasize that Bulma comes with &lt;em&gt;no javascript bundle&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;90% of the time, this isn’t a problem: all of the components Bulma has to offer work without any javascript. There is &lt;em&gt;one&lt;/em&gt; exception to this rule though, which you can find in the documentation &lt;a href="https://bulma.io/documentation/components/navbar/#navbar-menu" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;TL;DR: &lt;code&gt;navbar&lt;/code&gt; elements require some javascript to get them to appropriately collapse in mobile. The example they have on their site has a pretty extensive javascript that’ll handle multiple navbars. I’m usually only creating one as part of my layout, so I just slap some IDs on the elements I care about:&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;a&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"burger"&lt;/span&gt; &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="s"&gt;{toggleStyles}&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt; 
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-burger"&lt;/span&gt; &lt;span class="na"&gt;data-target=&lt;/span&gt;&lt;span class="s"&gt;"navMenu"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt; &lt;span class="na"&gt;aria-expanded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-menu"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"navbarmenu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- other elements here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Toggling whether or not to make the menu visible becomes trivial using a few selectors and an &lt;code&gt;onClick&lt;/code&gt; eventbound to that burger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
* Added this to toggle the is-active class. See:
* 
* https://bulma.io/documentation/components/navbar/#navbar-menu
* https://github.com/jgthms/bulma/issues/856
*/&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleStyles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#burger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is-active&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#navbarmenu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is-active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One other quick tip: Microsoft Edge has issues with how Bulma has implemented navbars, but this can be fixed with CSS. Multiple work-arounds can be found &lt;a href="https://github.com/jgthms/bulma/issues/2503" rel="noopener noreferrer"&gt;here&lt;/a&gt; depending onyour use-case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customization
&lt;/h2&gt;

&lt;p&gt;Bulma is very variable-oriented. Pretty much everything that has a default in Bulma can be customized. Colors, responsive breakpoints, fonts, you name it, anything can be customized!&lt;/p&gt;

&lt;p&gt;This comes in handy when you have a site that has a very particular color scheme. It’s possible to customize the colors and sizes of a lot of elements just by setting a variable.&lt;/p&gt;

&lt;p&gt;You can check out the full list of variables &lt;a href="https://bulma.io/documentation/customize/variables/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I’m one of those individuals who tries not to put CSS in too many places. As a stylistic preference, I’m not normally a fan of styles within HTML or JSX. I’ll normally write one Sass file, and overwrite Bulma’s variables as needed, and that way it gets applied throughout the whole site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#c01045&lt;/span&gt;
&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;'~bulma/scss/bulma.scss'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That color I chose was as close as I could get to spelling out “colors” in hexidecimal format, but in this example, we’re changing the &lt;code&gt;$primary&lt;/code&gt; color of Bulma. Bulma has a variety of colors that are available by default, and they can be used for a variety of purposes, including denoting success or indicating something that the user should give some attention to. Other colors like &lt;code&gt;$danger&lt;/code&gt; and &lt;code&gt;$warning&lt;/code&gt; can be customized to help apply the same color across multiple components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsiveness
&lt;/h2&gt;

&lt;p&gt;Bulma is responsive right out of the box. There are a number of breakpoints that Bulma comes packaged with, and they can be used in conjunction with styles to ensure that elements are displaying only when they’re supposed to be.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bulma.io/documentation/helpers/visibility-helpers/#hide" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is where an entire list of classes can be found that can help with displaying/hiding elements based on sceen size. For example, the following element displays differently based on screen size:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Please see the example on my blog &lt;a href="https://jvarness.blog/why-i-love-bulma/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This blog post was sourced from my blog and the embedded source won't work here :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Depending on your use-case, this could be a very nifty trick up your Bulma sleeve.&lt;/p&gt;

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

&lt;p&gt;I hope that I’ve sparked a little bit of interest in Bulma with this post. If you’ve got any feedback for me, I’d love to hear back from you!&lt;/p&gt;

</description>
      <category>css</category>
      <category>scss</category>
    </item>
    <item>
      <title>Why was 0110 afraid of 0111?</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Wed, 03 Jul 2019 21:05:01 +0000</pubDate>
      <link>https://dev.to/jvarness/why-was-0110-afraid-of-0111-56nc</link>
      <guid>https://dev.to/jvarness/why-was-0110-afraid-of-0111-56nc</guid>
      <description>&lt;p&gt;Because 0111 1000 1001!!! 😂&lt;/p&gt;

</description>
      <category>jokes</category>
    </item>
    <item>
      <title>Talking to the Internet with the ESP32 Feather</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Fri, 08 Mar 2019 00:50:37 +0000</pubDate>
      <link>https://dev.to/jvarness/talking-to-the-internet-with-the-esp32-feather-35a6</link>
      <guid>https://dev.to/jvarness/talking-to-the-internet-with-the-esp32-feather-35a6</guid>
      <description>&lt;p&gt;I've been away from a little bit, but I'm back to discuss what I've been working on offline!&lt;/p&gt;

&lt;p&gt;My super awesome wife purchased some super awesome little development boards for me for Christmas a couple of months ago! I tweeted this a few weeks ago:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1097868615762804738-708" src="https://platform.twitter.com/embed/Tweet.html?id=1097868615762804738"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1097868615762804738-708');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1097868615762804738&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The project currently displays random information about random Magic: The Gathering cards, but I'm eventually turning this into a little weather station for my desk. I figured I'd come over to my favorite little corner of the internet and show it off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Talk Hardware
&lt;/h2&gt;

&lt;p&gt;Let's start with the board and other tech I'm using. All of these components are from &lt;a href="https://www.adafruit.com/" rel="noopener noreferrer"&gt;Adafruit&lt;/a&gt;, an electronics company that makes and sells all kinds of interesting little components for tinkering and making anything your heart desires!&lt;/p&gt;

&lt;p&gt;Specifically, this project uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.adafruit.com/product/3405" rel="noopener noreferrer"&gt;ESP32 Feather&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A microcontroller packed with WiFi and Bluetooth capabilities, and a myriad of other things that make this board extremely versatile for IoT projects.&lt;/li&gt;
&lt;li&gt;Mine is the one that came with stacking headers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://www.adafruit.com/product/2900" rel="noopener noreferrer"&gt;OLED Featherwing&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A breakout board with a 128x32 OLED screen attached.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;3D-printed case designed for Adafruit Feathers (&lt;a href="https://www.thingiverse.com/thing:2209964" rel="noopener noreferrer"&gt;link to thingiverse&lt;/a&gt;)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;One of the neatest things about the Adafruit Feather line is the Featherwings that you can optionally purchase for the board. In the tweet, what you're seeing is the OLED Featherwing that's &lt;em&gt;attached&lt;/em&gt; to the ESP32 Feather using the stacking header pins.&lt;/p&gt;

&lt;p&gt;The 3D printed case is just cool :D&lt;/p&gt;

&lt;p&gt;Why did I choose the Feather for this project? For multiple reasons. First and foremost, the Feather line has many options for breakout boards that follow the same form factor as the boards themselves. All are stackable, and can change the capabilities of your board simply by switching them out!&lt;/p&gt;

&lt;p&gt;Another reason is the size. I have a number of different boards: an Arduino Uno, Arduino Micro, Raspberry Pi Zero, and a couple Raspberry Pi 2s. Raspberry Pi is an excellent choice if you need the full capabilities of a Linux OS in a tiny space, and the newer boards even come with built-in wireless receivers. I didn't really need Linux though, and thought that the Feather offered a little more than my Arduinos did, for a smaller or comparable size.&lt;/p&gt;

&lt;p&gt;The third main reason has to do with the software involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  How About the Software?
&lt;/h2&gt;

&lt;p&gt;Feather boards can be programmed with the Arduino IDE, and you can utilize many popular Arduino libraries right out of the box. Writing Arduino code feels a lot like writing code for a Pebble watch: you can write a small C program that does a lot!&lt;/p&gt;

&lt;p&gt;Here's a link to the &lt;a href="https://github.com/jvarness/arduino/blob/master/esp32/esp32_demo.ino" rel="noopener noreferrer"&gt;code&lt;/a&gt;. (Please don't actually use &lt;code&gt;SSID&lt;/code&gt; as your actual SSID or &lt;code&gt;password123&lt;/code&gt; as any password ever.)&lt;/p&gt;

&lt;p&gt;Of the libraries I'm using, the most notable ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://arduinojson.org" rel="noopener noreferrer"&gt;ArduinoJson&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A magical library that allows you to parse JSON objects elegantly on the Arduino platform.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;WifiClientSecure

&lt;ul&gt;
&lt;li&gt;Allows you to connect to the WiFi and make HTTPS calls.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Adafruit OLED Driver

&lt;ul&gt;
&lt;li&gt;Makes writing text to the OLED really easy.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://scryfall.com" rel="noopener noreferrer"&gt;Scryfall&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;An online reference for Magic: The Gathering cards that has a REST API.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Honestly, the most difficult part of writing the code was just getting the board to connect to the WiFi and making an HTTPS call!&lt;/p&gt;

&lt;p&gt;In a lot of programming languages, internet-related tasks are abstracted away to the point where you don't normally have to think about creating the connection to the internet and hand-writing an HTTP packet.&lt;/p&gt;

&lt;p&gt;ArduinoJson makes it really easy to parse JSON bodies in Arduino though, so that part wasn't so bad.&lt;/p&gt;

&lt;p&gt;The code is still pretty rough, and I haven't commented it, and it actually has a flaw in it that I need to fix:&lt;/p&gt;

&lt;p&gt;After a while, the &lt;code&gt;client&lt;/code&gt; becomes unavailable and stops making HTTP calls. I think I might have to figure out how to reconnect the client if it becomes unavailable. At first I may have thought Scryfall was disconnecting me due to rate-limiting, but I don't &lt;em&gt;think&lt;/em&gt; that's what it is since I'm only hitting it every 1/3 of a second. If you know what I'm doing wrong, lemme know!&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Product
&lt;/h2&gt;

&lt;p&gt;The result is pretty cool I think: a small board that displays random information from the interwebs.&lt;/p&gt;

&lt;p&gt;While this is just a small example of what this board is capable of, it's a good starting point for me, and it's going to be reminiscent of what my goal is for the board!&lt;/p&gt;

&lt;p&gt;That's all I got for now guys. If you guys have any questions or if you know what I did wrong in my code, or if you liked the post, drop a comment and lemme know your thoughts!&lt;/p&gt;

</description>
      <category>adafruit</category>
      <category>arduino</category>
    </item>
    <item>
      <title>32 Lines of Code</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Sun, 28 Oct 2018 16:04:14 +0000</pubDate>
      <link>https://dev.to/jvarness/32-lines-of-code-4bgc</link>
      <guid>https://dev.to/jvarness/32-lines-of-code-4bgc</guid>
      <description>&lt;p&gt;At &lt;a href="https://www.cerner.com/" rel="noopener noreferrer"&gt;Cerner&lt;/a&gt;, we engineers work really hard to deliver innovative health care solutions. However, we also play (and hack) hard too!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1055902128353488896-353" src="https://platform.twitter.com/embed/Tweet.html?id=1055902128353488896"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1055902128353488896-353');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1055902128353488896&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Among a list of Cerner's internal hackathons is a programming competition called 2^5. The rules for this competition are fairly simple: for 32 days you can make one submission per day that's 32 lines or less of code.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1055560488594087940-226" src="https://platform.twitter.com/embed/Tweet.html?id=1055560488594087940"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1055560488594087940-226');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1055560488594087940&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;This was my second year participating in the competition, and I gotta say... It's super fun. Here are a couple things I learned this year during the competition:&lt;/p&gt;

&lt;h1&gt;
  
  
  32 lines can be powerful
&lt;/h1&gt;

&lt;p&gt;Ever deploy an enterprise application that was 32 lines or less that you never had to maintain? Me neither.&lt;/p&gt;

&lt;p&gt;However, it's incredible how you can make simple applications using 32 lines of code. Take my &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2018/JS/vue-todo" rel="noopener noreferrer"&gt;submission that uses Vue&lt;/a&gt; as an example. Todo App is a pretty classic app to write as a &lt;code&gt;hello, world!&lt;/code&gt; replacement for web development.&lt;/p&gt;

&lt;p&gt;This little app just uses &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; and &lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;bootstrap&lt;/a&gt; to create a small application to list out all the things you have to do in a way that looks somewhat visually appealing. Will it sync up to the cloud? No. Was I able to add a button to each item that would allow you to delete it? No (would have made the submission more than 32 lines). Is it a good starting point for learning two extremely popular web technologies? Yes indeed.&lt;/p&gt;

&lt;p&gt;Even if your 32 lines doesn't really do anything that's "cool" or "noteworthy", it can still act as a foray into expanding your knowledge. That's what a lot of my 2^5 submissions were meant to help me do: learn things I didn't know before.&lt;/p&gt;

&lt;h1&gt;
  
  
  The web now owns your favorite language
&lt;/h1&gt;

&lt;p&gt;Don't believe me? Just look at my submissions:&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin
&lt;/h2&gt;

&lt;p&gt;If you write any &lt;a href="https://kotlinlang.org/" rel="noopener noreferrer"&gt;Kotlin&lt;/a&gt; code or have read the docs, you know that Kotlin can be compiled into JavaScript to allow you to write front-end web application code, and it's also becoming (if not already) the defacto standard for writing native Android applications.&lt;/p&gt;

&lt;p&gt;But did you know that you can use Kotlin to create web services as well? I certainly didn't until I found &lt;a href="https://ktor.io/" rel="noopener noreferrer"&gt;ktor&lt;/a&gt;, a Kotlin web framework for making web services.&lt;/p&gt;

&lt;p&gt;I was able to write small snippets of code using Kotlin to write &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2018/Kotlin/hello-ktor" rel="noopener noreferrer"&gt;web services&lt;/a&gt; as well as &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2018/Kotlin/ktor-sockets" rel="noopener noreferrer"&gt;web sockets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For those of you who might use Kotlin to write applications, this is really great, as it means that your whole technology stack can be written front-to-back in Kotlin!&lt;/p&gt;

&lt;h2&gt;
  
  
  Swift
&lt;/h2&gt;

&lt;p&gt;I wasn't going to write about Kotlin without giving at least a little bit of attention to the Apple fanboys/fangirls out there!&lt;/p&gt;

&lt;p&gt;If you write code in &lt;a href="https://developer.apple.com/swift/" rel="noopener noreferrer"&gt;Swift&lt;/a&gt; already, you probably know that you can write iOS and macOS applications using Swift and Apple's native libraries. However, did you also know that you can create a web service using Swift as well?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2018/Swift/HelloVapor" rel="noopener noreferrer"&gt;One of my submissions&lt;/a&gt; in Swift uses a library called &lt;a href="https://vapor.codes/" rel="noopener noreferrer"&gt;Vapor&lt;/a&gt; to write a small microservice that calculates the Nth fibonnaci number.&lt;/p&gt;

&lt;p&gt;Apple engineers can now also write their whole tech stack in Swift as well! All of this innovation is great news for developers because they don't have to make investments in multiple languages in order to perform the work they need to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Others
&lt;/h2&gt;

&lt;p&gt;Of course Kotlin and Swift aren't the only languages that could bode good news for developers. I didn't have time to make submissions in all these other languages, but &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-2.1" rel="noopener noreferrer"&gt;.NET Core&lt;/a&gt; is another great option, as well as &lt;a href="https://www.dartlang.org/dart-vm" rel="noopener noreferrer"&gt;Dart&lt;/a&gt; for all you &lt;a href="https://flutter.io/" rel="noopener noreferrer"&gt;Flutter&lt;/a&gt; enthusiasts out there.&lt;/p&gt;

&lt;p&gt;If you look hard enough, you'll probably find a way to create a web application or microservices using your favorite language. Is it going to always be practical to do that? Not necessarily, but it's possible at least!&lt;/p&gt;

&lt;h1&gt;
  
  
  Technology is growing and becoming more diverse
&lt;/h1&gt;

&lt;p&gt;When I graduated from college in 2014, 90% of my skillset involved experience in Android, WPF, and Java services. C# and Java was really all that I knew.&lt;/p&gt;

&lt;p&gt;Looking back on the last few years of my career, I have learned &lt;em&gt;so many different langauges&lt;/em&gt;. I have all of my submissions from the last two years in this Github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jvarness" rel="noopener noreferrer"&gt;
        jvarness
      &lt;/a&gt; / &lt;a href="https://github.com/jvarness/cerner-2-to-the-5th" rel="noopener noreferrer"&gt;
        cerner-2-to-the-5th
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Submissions for 2^5
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;cerner-2-to-the-5th&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Submissions for 2^5.&lt;/p&gt;
&lt;p&gt;Assume MIT license for all submissions.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jvarness/cerner-2-to-the-5th" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;I went from knowing... Really only 2 languages to learning a little over a dozen in a couple of years!&lt;/p&gt;

&lt;p&gt;Many of the languages I know now seem to really only have gained traction over the past couple of years: Go, Dart, and Elm have been in active development for quite some time, and each have grown in popularity drastically since I graduated.&lt;/p&gt;

&lt;p&gt;Even if I haven't really developed full-fledged applications in these languages, I have at least had opportunities to learn them. Participating in competitions like 2^5 gives me an chance to become a little more diverse in my skillset.&lt;/p&gt;

&lt;p&gt;Thanks for taking the time to read this, and I hope you guys enjoyed all the little snippets and stuff I shared today! If you have questions about anything I've written about, or about the code I wrote, drop a comment!&lt;/p&gt;

</description>
      <category>career</category>
      <category>programming</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What Nursery Rhymes Teach Us About The DRY Principle</title>
      <dc:creator>Jake Varness</dc:creator>
      <pubDate>Tue, 15 May 2018 17:23:04 +0000</pubDate>
      <link>https://dev.to/jvarness/what-nursery-rhymes-teach-us-about-the-dry-principle-4j5g</link>
      <guid>https://dev.to/jvarness/what-nursery-rhymes-teach-us-about-the-dry-principle-4j5g</guid>
      <description>&lt;p&gt;For those of you who don't know, I'm a father! I have a son who was born just last year!&lt;/p&gt;

&lt;p&gt;As a result, I've had to listen to a lot (and I mean A LOT) of different nursery rhymes. Some I've never heard before. Some I have, but I never really paid much attention to them.&lt;/p&gt;

&lt;p&gt;That is until I heard the song &lt;em&gt;5 Little Monkeys Jumping On The Bed&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lmgtfy.com/?q=5+little+monkeys+jumping+on+the+bed" rel="noopener noreferrer"&gt;I googled it for you&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Plot
&lt;/h1&gt;

&lt;p&gt;The premise of this nursery rhyme is very simple: there are a total of five ill-behaved monkeys that are jumping on a bed.&lt;/p&gt;

&lt;p&gt;During the group's collective effort to jump as high as they can and cause as much ruckus as possible, each monkey takes turns falling off of the bed, causing bodily injury requiring the mother of the monkeys to call a doctor, who subsequently tells the mother "no more monkeys jumping on the bed".&lt;/p&gt;

&lt;p&gt;The mother, whilst diligently attending to the monkey who is currently injured, neglects the fact that many other monkeys are also jumping on the same bed. As each monkey falls off, the mother tends to each child individually, one-by-one, until there aren't any monkeys jumping on the bed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Breakdown
&lt;/h1&gt;

&lt;p&gt;There are multiple things at play here:&lt;/p&gt;

&lt;p&gt;First, each monkey is performing a similar action, and each monkey subsequently fails in a similar fashion as well. &lt;/p&gt;

&lt;p&gt;Second, rather than instructing all of the monkeys to behave, the mother decides to only focus on the monkeys that have demonstrated the problem until all are tamed.&lt;/p&gt;

&lt;p&gt;Finally, once each are tamed, the monkeys each stop jumping on the bed. However, because each monkey is still sentient and each have a disposition to poor behavior, each monkey is likely to perform actions that could cause further harm to themselves and those around them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Possible Solutions
&lt;/h1&gt;

&lt;p&gt;We can't solve the mother's problem of having 5 monkeys that enjoy getting themselves into trouble, and try as we might to correct their behavior, they are still prone to misbehaving.&lt;/p&gt;

&lt;p&gt;We also can't mitigate this issue by consolidating the monkeys and reducing them to 1 monkey, so unfortunately the mother might just have to live with her 5 little monkeys until they move out of the house.&lt;/p&gt;

&lt;p&gt;For us programmers, however, reducing the amount of monkeys in our code is very possible!&lt;/p&gt;

&lt;h1&gt;
  
  
  The DRY Principle
&lt;/h1&gt;

&lt;p&gt;Contrary to what the name might suggest, the DRY Principle has nothing to do with how wet &lt;del&gt;water&lt;/del&gt; your code is.&lt;/p&gt;

&lt;p&gt;DRY is an acronym that stands for &lt;strong&gt;Don't Repeat Yourself&lt;/strong&gt;. This stems from the idea that your codebase shouldn't have duplicated code in it.&lt;/p&gt;

&lt;p&gt;But why not? I mean, if the code works for what you need it for, why not just copy/paste it wherever you need it?&lt;/p&gt;

&lt;p&gt;For the same reason that the mother should have stopped all her little monkeys from jumping off the bed: &lt;em&gt;you're just going to keep getting hurt by it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you duplicate code, you duplicate all previous issues the code had, and gain none of the future benefits that future code changes can provide. All you get when you duplicate code is a monkey jumping on the bed that is your source code.&lt;/p&gt;

&lt;p&gt;Take this code for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isPrimeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously this JavaScript code is problematic for a number of reasons: first, it assumes that if a number is not evenly divisible by 2 that it's a prime number. Second, it assumes that the variable passed in is always some kind of numeric value that you can perform integer division on.&lt;/p&gt;

&lt;p&gt;Other engineers who see this code might decide that to keep the same behavior throughout the rest of the system, the code needs to be duplicated to other places.&lt;/p&gt;

&lt;p&gt;Now that this function exists in multiple places within the codebase, the problem has spread to other places in the system. The monkey that used to be isolated has now multiplied and they are running rampant throughout the system.&lt;/p&gt;

&lt;p&gt;What would have been better is if this function were extracted into it's own reusable component and updated to have the correct functionality in later versions. That would have tamed the monkey from the start!&lt;/p&gt;

&lt;p&gt;Duplicating later versions of this function, however, does not remedy this problem. Duplication also causes a lot of manual intervention and unnecessary work to maintain and update in the future. Every time the original function is updated, the clones of it would need to be updated as well. If your code is going to have a monkey in it, ensure there's only one monkey: don't repeat your monkeys.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope that this article has been very informative and enlightening. As silly as this example is, it just goes to show you that you can find good programming advice and lessons in a lot of different places!&lt;/p&gt;

</description>
      <category>dry</category>
      <category>nurseryrhymes</category>
      <category>career</category>
    </item>
  </channel>
</rss>
