<?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: mattIshida</title>
    <description>The latest articles on DEV Community by mattIshida (@mattishida).</description>
    <link>https://dev.to/mattishida</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%2F1002204%2F0910964d-1b50-4ade-842e-bc5a202189af.png</url>
      <title>DEV Community: mattIshida</title>
      <link>https://dev.to/mattishida</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mattishida"/>
    <language>en</language>
    <item>
      <title>A gotcha with Next.js production builds in Docker Compose</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Wed, 26 Apr 2023 23:20:01 +0000</pubDate>
      <link>https://dev.to/mattishida/a-gotcha-with-nextjs-production-builds-in-docker-compose-2232</link>
      <guid>https://dev.to/mattishida/a-gotcha-with-nextjs-production-builds-in-docker-compose-2232</guid>
      <description>&lt;p&gt;This post discusses a gotcha or pitfall I ran into when learning Next.js and Docker. It's pretty elementary, but I couldn't find discussions of it online. ChatGPT wasn't especially helpful either, so hopefully this post saves another newb some time and frustration. &lt;/p&gt;

&lt;p&gt;TL;DR: you can put &lt;code&gt;npm run build&lt;/code&gt; in a command to run when the container starts, not when the image builds. &lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: Docker builds succeed in dev but not prod
&lt;/h2&gt;

&lt;p&gt;I had a Docker Compose file defining backend and frontend services, the latter a Next.js app. I was able to build the images and start the containers fine in a development environment. But in production it failed every single time!&lt;/p&gt;

&lt;p&gt;The error was typically some version of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FetchError: request to http://backend:4000/users failed
reason: getaddrinfo ENOTFOUND backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In plain English, the frontend was unable to fetch data from the backend when Next.js went to build the production version of the app.&lt;/p&gt;

&lt;p&gt;But it worked fine in dev!!!&lt;/p&gt;

&lt;p&gt;Right?&lt;/p&gt;

&lt;p&gt;Riiiiight?...&lt;/p&gt;

&lt;p&gt;But was it actually working in dev? Was the frontend fetching data from the backend at build time? &lt;/p&gt;

&lt;p&gt;Hint: no.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSG and &lt;code&gt;npm run build&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next.js offers some great features like static-site generation (SSG). Static-site generation means that the server pre-fetches data so that it can use that data to generate completed HTML and then serve that HTML to web browsers in production. Now &lt;em&gt;when&lt;/em&gt; is that data fetched? Answer: on running &lt;code&gt;npm run build&lt;/code&gt; (or &lt;code&gt;next build&lt;/code&gt;) &lt;em&gt;prior&lt;/em&gt; to starting to the frontend server.&lt;/p&gt;

&lt;p&gt;So building a production-ready SSG-enabled Next.js app requires access to backend data. Which means that the server supplying that data needs to be up and running first. &lt;/p&gt;

&lt;p&gt;By contrast, in development, no static HTML is generated so there is no build step requiring data to be pre-fetched.&lt;/p&gt;

&lt;p&gt;In essence, then, my error boils down to including &lt;code&gt;RUN npm run build&lt;/code&gt; in my production frontend Dockerfile and then using Docker compose to build both services before starting either. &lt;/p&gt;

&lt;p&gt;I was trying to tell Next.js to build a static site before the backend server was up and running to supply the necessary data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix it?
&lt;/h2&gt;

&lt;p&gt;That explains why I was running into the error. But how to resolve it?&lt;/p&gt;

&lt;p&gt;First, the problem is muddied by semantic confusion over the term &lt;code&gt;build&lt;/code&gt;. Docker builds images and Next.js builds a statically generated site. It's natural at first to think these are similar operations that need to go together. &lt;/p&gt;

&lt;p&gt;But there's no necessary connection between them. Building the Docker image is a matter of packaging an app together with its dependencies and runtime environment. Building a statically generated site is a matter of fetching data and compiling React and JavaScript into optimized HTML.&lt;/p&gt;

&lt;p&gt;If the data is there to be fetched, the latter build can happen as part of the former. But, as in my case, if the data is not there, the Next.js build has to wait.&lt;/p&gt;

&lt;p&gt;So the problem can be rephrased as: how to build the backend and frontend Docker images first, then start the backend server, then do the Next.js build, then start the frontend server. &lt;/p&gt;

&lt;h2&gt;
  
  
  Docker entrypoints
&lt;/h2&gt;

&lt;p&gt;Can't we just use the &lt;code&gt;depends_on&lt;/code&gt; directive in the Docker compose file? &lt;code&gt;depends_on&lt;/code&gt; says "don't start A without first starting B." And, yes, we want to make sure the backend service starts first. But there's a bit more to it. &lt;/p&gt;

&lt;p&gt;We also need to make sure that the Next.js build happens after the backend starts. &lt;code&gt;depends_on&lt;/code&gt; establishes a start dependency, not a build dependency. We could solve our problem if there were a Docker compose directive to say "don't build A without first starting B", but as far as I know there isn't. &lt;/p&gt;

&lt;p&gt;What we can do is separate building the frontend Docker image from building the statically generated site. That way &lt;code&gt;depends_on&lt;/code&gt; will ensure that the Next.js build happens at the right time. &lt;/p&gt;

&lt;p&gt;The easiest way I found to do this is with a simple docker-entrypoint.sh file. Entrypoints are scripts for specifying commands to run when a container starts up. Exactly what we need! The hard part was just realizing the Next.js build could happen on container start not on image build. &lt;/p&gt;

&lt;p&gt;My docker-entrypoint.sh file looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Build the Next site including SSG
npm run build

# Start the production server
npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward. &lt;/p&gt;

&lt;p&gt;And the final step was just invoking the entrypoint as the final lines in my frontend dockerfile, replacing the &lt;code&gt;CMD ['npm', 'run', 'dev']&lt;/code&gt; line that was there previously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/bin/sh", "/docker-entrypoint.sh"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line above copies the script into the Docker image, the second makes it executable, and the third executes it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Learning new technologies often means learning different uses of the same word, 'build' for example. Don't assume they mean the same thing! Be sensitive to what the words are doing in context--the concepts are likely different, maybe radically, maybe only very slightly. Once we clarify the underlying the concepts, the code usually follows.     &lt;/p&gt;

</description>
      <category>docker</category>
      <category>nextjs</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Rails authentication: thinking above the code</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Fri, 03 Mar 2023 22:01:50 +0000</pubDate>
      <link>https://dev.to/mattishida/rails-authentication-thinking-above-the-code-3b9o</link>
      <guid>https://dev.to/mattishida/rails-authentication-thinking-above-the-code-3b9o</guid>
      <description>&lt;p&gt;Most things in Rails are remarkably easy. Surprisingly easy. But authentication and authorization are not. Not that Rails isn't doing a lot under the hood to make them &lt;em&gt;easier&lt;/em&gt;. But it can be a bit of shock to go from setting up a simple API in literally minutes, to puzzling over how to implement signup, authentication, authorization, auto-login, and logout using a number of interconnected controllers, objects, and methods, many of them custom. &lt;/p&gt;

&lt;p&gt;In this point, I'm going to try to "think above the code" to understand what is really going on and hopefully bring a modicum of order to the code itself. The goal is to see the syntactic complexity as the surface layer of something that is more abstract, but also simpler and therefore easier to remember and reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from zero: auth as a conversation
&lt;/h2&gt;

&lt;p&gt;If we were designing "auth" for websites from scratch, what would we need? &lt;/p&gt;

&lt;p&gt;To make things more vivid, let's use an analogy. If we were designing a humanoid robot that was capable of rich and meaningful conversations with people, what would we need? &lt;/p&gt;

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

&lt;p&gt;The idea here is that authentication on website should feel like having a conversation with someone who knows who you are and responds to your individual characteristics.&lt;/p&gt;

&lt;h3&gt;
  
  
  User data
&lt;/h3&gt;

&lt;p&gt;Most obviously, we would need to know about users. We would need to store data about them, including but not necessarily limited to their identifying characteristics, of which username and password are the most obvious. &lt;/p&gt;

&lt;p&gt;Going back to our metaphor, if our robot is going to be capable of carrying on rich and meaningful conversations with people, it will need a store of user data like name, facial appearance, age, likes and dislikes, last conversation, etc. &lt;/p&gt;

&lt;p&gt;In Rails terms, we're going to need a &lt;code&gt;User&lt;/code&gt; resource. We're going to want to be able to add and retrieve users as needed, so we'll want users#create and &lt;code&gt;users#show&lt;/code&gt; routes, at a minimum.   &lt;/p&gt;

&lt;h3&gt;
  
  
  Back-end State
&lt;/h3&gt;

&lt;p&gt;Is it enough simply to know about users? It's kind of an interesting question. Go back to our robot analogy. Is it enough for our robot to have access to user data?&lt;/p&gt;

&lt;p&gt;No. &lt;/p&gt;

&lt;p&gt;The goal is not just to have a store of user data but to have robot that can converse meaningfully on a user-by-user basis. All the user data in the world would be of no use unless the robot also knew &lt;em&gt;who&lt;/em&gt; it was talking to at any particular moment. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12s29v22t0g1dhb5v2d7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12s29v22t0g1dhb5v2d7.png" alt=" " width="630" height="452"&gt;&lt;/a&gt;&lt;br&gt;
vs.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6eouggierj0dlpzwtja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6eouggierj0dlpzwtja.png" alt=" " width="600" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our robot therefore needs some representation of "the here and now." The user table by itself doesn't pick out any user as the one being spoken to. It's just a series of hundreds maybe thousands of rows, each resembling the last. The table by itself is completely neutral whereas our here-and-now representation needs to be highly particular.&lt;/p&gt;

&lt;p&gt;So we'll need some representation of the here and now state that picks out particular user as a conversational partner. For now, I'll simply refer to this representation as the state.&lt;/p&gt;

&lt;p&gt;In Rails terms, is state simply another resource? Well, we may want to create, update, and destroy state, which will mean creating routes and a state controller. But state can't be just another resource. It has a special role to play. Creating another table with rows mapped to state instances isn't enough, just as having a bunch of acquaintances stored in memory doesn't tell you who you are talking to &lt;em&gt;right now&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;State needs to be it's own thing! In Rails, state is represented as an object named "session" with a &lt;code&gt;:user_id&lt;/code&gt; attribute. &lt;/p&gt;
&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;We've actually made progress. We've established a foundation.  We know that we're going to be basing all of our auth activities on two entities: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A store of user data in the form of a user table that represents the individuals we know about&lt;/li&gt;
&lt;li&gt;A back-end state representation in the form of session object with &lt;code&gt;:user_id&lt;/code&gt; attribute that represents who we are talking to in the here and now. By convention, if there isn't any such person &lt;code&gt;:user_id&lt;/code&gt; will be &lt;code&gt;nil&lt;/code&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, when we are trying to implement a certain functionality, we can think in terms of these two entities. The first question is what do we want to do to these two entities, then  which Rails methods do we need to do that.&lt;/p&gt;

&lt;p&gt;Let's walk through some standard auth functions one by one and see how the map to our entities. &lt;/p&gt;
&lt;h3&gt;
  
  
  Signup
&lt;/h3&gt;

&lt;p&gt;Here we are creating a new user and then allowing that user to actually start using the website. &lt;/p&gt;

&lt;p&gt;In terms of our robot, we are introducing a new acquaintance and having the robot start a conversation with that acquaintance.&lt;/p&gt;

&lt;p&gt;So we'll want to 1) add a user to the user table and 2) update the session[:user_id] attribute to start the "conversation".&lt;/p&gt;
&lt;h3&gt;
  
  
  Login
&lt;/h3&gt;

&lt;p&gt;Here we are checking if a user's credentials match anything in our store of user data. If the check is successful, the user will start using the website. &lt;/p&gt;

&lt;p&gt;In terms of our robot, the robot is recognizing a previous conversation partner, then initiating a conversation with that individual. &lt;/p&gt;

&lt;p&gt;So we'll want to 1) check the contents of user table against the submitted credentials and 2) update the &lt;code&gt;session[:user_id]&lt;/code&gt; attribute to start the "conversation."&lt;/p&gt;

&lt;p&gt;In Rails, authentication per se is really just a part of our concept of checking the user table against credentials. It can be accomplished with a simple call to the &lt;code&gt;authenticate&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user = User.find_by(username: params[:username])
user&amp;amp;.authenticate(params[:password])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authorization
&lt;/h3&gt;

&lt;p&gt;Authorization is distinct from signup and login insofar as it involves checking the properties of a user who has &lt;em&gt;already&lt;/em&gt; logged in.&lt;/p&gt;

&lt;p&gt;In terms of our robot, we can think of this as the robot retrieving information about its current conversational partner and checking that information for guidance about how to respond.&lt;/p&gt;

&lt;p&gt;Here the session[:user_id] has already been set as the conversation can be assumed to initiated. The problem is that the &lt;code&gt;:user_id&lt;/code&gt; is just a reference to a record in table. The session object doesn't contain the user instance itself. We still need to retrieve the data in the record so we can decide how to act on it.&lt;/p&gt;

&lt;p&gt;Hence, we need to set an instance variable &lt;code&gt;@user&lt;/code&gt; based on the &lt;code&gt;:user id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@user = User.find_by(id: session[:user_id])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This points up one limitation of how Rails represents our concept of the 'here and now' back-end state. It doesn't contain the full user instance. So we need to explicitly retrieve that information as a step in the authorization process before any action that retrieves user-specific information. &lt;/p&gt;

&lt;h3&gt;
  
  
  Logout
&lt;/h3&gt;

&lt;p&gt;Logout is analogous to ending a conversation. Ending a conversation doesn't mean forgetting that individual, so we know we'll be leaving the users table alone. All we really need to do is update the &lt;code&gt;session[:user_id]&lt;/code&gt; attribute to reflect the change to a null state. &lt;/p&gt;

&lt;p&gt;Since a nil &lt;code&gt;:user_id&lt;/code&gt; is equivalent to a state of 'no-conversation' we can accomplish this simply by deleting the attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;session.delete :user_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Auto-Login
&lt;/h3&gt;

&lt;p&gt;Auto-login is an interesting case. For present purposes, auto-login is analogous to a situation where a conversation with our robot is already in place. The user table and &lt;code&gt;session[:user_id]&lt;/code&gt; are just as they should be. We simply need to check if there is non-nil :&lt;code&gt;user_id&lt;/code&gt; attribute and, if there is, send that information for that user to the front end.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Since the point of this post is to reduce complexity, we can start to organize our auth functionality by what kinds of things we are doing to which of our two key entities. As a shorthand: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Signup: Table update, back-end state update&lt;/li&gt;
&lt;li&gt;Login: Table check, back-end state update&lt;/li&gt;
&lt;li&gt;Authorization: back-end state check &lt;/li&gt;
&lt;li&gt;Logout: back-end state update&lt;/li&gt;
&lt;li&gt;Auto-Login: back-end state check&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Again, by table here we mean our store of user data and by state we mean our representation of the "conversation" taking place.&lt;/p&gt;

&lt;p&gt;One of the important caveats is that our state representation can't hold full user data, so checking state will typically mean setting an instance variable &lt;code&gt;@user&lt;/code&gt; which contains the relevant data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping to MVC
&lt;/h2&gt;

&lt;p&gt;The next difficult thing about auth in Rails is mapping these concepts to routes and controllers.&lt;/p&gt;

&lt;p&gt;Unfortunately, here is where some of the line start to get a little blurry. It becomes harder to maintain a traditional separation of concerns. &lt;/p&gt;

&lt;p&gt;We've seen that auth is based on a users table and session object. As a first pass, it is tempting to assume that we will need Rails resources for both of these, so that each have their own table, model, controller, and RESTFUL routes. &lt;/p&gt;

&lt;p&gt;However, we need to depart from the typical Rails setup for a number of reasons.&lt;/p&gt;

&lt;p&gt;1) The session object is not just another Rails resource. As we've seen it has an important role to play as the representation of back-end state.&lt;br&gt;
2) User controller actions like &lt;code&gt;create&lt;/code&gt; (for user signup) and &lt;code&gt;show&lt;/code&gt; (for user auto-login) will need to update the session object.&lt;br&gt;
3) Session controller actions like &lt;code&gt;create&lt;/code&gt; (for user login)  and &lt;code&gt;destroy&lt;/code&gt; (for logout) do not actually create or destroy the session. Instead, they update the &lt;code&gt;session[:user_id]&lt;/code&gt; attribute.&lt;br&gt;
4) There is an important action of setting a &lt;code&gt;@user&lt;/code&gt; instance variable based on our back-end state. While this crucially involves the &lt;code&gt;session[:user_id]&lt;/code&gt; attribute, it is not an action in the session controller. Instead, it needs to be set again before every action (regardless of controller) that requires authorization. This is typically done with a Rails &lt;code&gt;before_action&lt;/code&gt; filter.&lt;/p&gt;

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

&lt;p&gt;Implementing auth can be better understood by thinking of it in terms of more abstract but more elementary concepts. To be sure, the fit is not altogether clean, especially on some of the finer details. But seeing those mismatches can itself be a useful tool in remembering the ins-and-outs of this complicated topic.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>rxjs</category>
      <category>http</category>
    </item>
    <item>
      <title>Polymorphic associations in Active Record</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Tue, 21 Feb 2023 21:48:33 +0000</pubDate>
      <link>https://dev.to/mattishida/polymorphic-associations-in-active-record-2pjk</link>
      <guid>https://dev.to/mattishida/polymorphic-associations-in-active-record-2pjk</guid>
      <description>&lt;p&gt;As a software developer, one of the best feelings has to be thinking up a great feature for your project, wondering anxiously if it can done, then finding it's a built-in feature of the library you're already working with. Read the docs--it pays!&lt;/p&gt;

&lt;p&gt;In this blog post, I'll go over setting up polymorphic database relations in Active Record. Not only is it possible, it's surprisingly painless and useful.&lt;/p&gt;

&lt;h1&gt;
  
  
  Polymorphic???
&lt;/h1&gt;

&lt;p&gt;The word "polymorphic" can be a bit of stumbling block. Let's quickly try to demystify it.&lt;/p&gt;

&lt;p&gt;Normally, we think of a database relationships as modeled on something concrete and specific. If we have a table of episodes and a table of TV shows, how should the two tables be related?&lt;/p&gt;

&lt;p&gt;To answer that question, we think about the real-world relationship of episodes and shows. An episode is, by definition, part of series linked together by a running theme and a core group of personnel behind the scenes. It's an expression of a piece intellectual property that can be thought of as a single entity, namely a show. &lt;/p&gt;

&lt;p&gt;Thinking through that relation, it's clear that there is a unique show for each episode, whereas a show can (and ideally should) have many episodes.&lt;/p&gt;

&lt;p&gt;This guides how we set up our Active Record migrations and models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Episode &amp;lt; ActiveRecord::Base
  belongs_to :show
end

class Show &amp;lt; ActiveRecord::Base
  has_many :episodes
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Episodes and shows are a very concrete relationship. So are ingredients and recipes, or employees and managers, or even Amazon users and orders.&lt;/p&gt;

&lt;p&gt;But what about relations that are less concrete? &lt;/p&gt;

&lt;p&gt;What about the relation of liking? I can like all sorts of things, almost anything at all, in fact, whether concrete or abstract. I can like strawberry ice cream or going to the movies or my last vacation or my neighbor's dog. I can like the show, or particular episodes, or the actors in the show, or even moments within the show.&lt;/p&gt;

&lt;p&gt;If you tell me you have a sibling relation to some entity X, I know what kind of thing X is, namely a human being. If you tell me you like some entity X, I have no way of knowing what that is. At most, I can say it is the kind of thing that can be liked, which isn't much at all.&lt;/p&gt;

&lt;p&gt;Liking is &lt;strong&gt;polymorphic&lt;/strong&gt;. It's not particular about the kinds of things it relates.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use cases
&lt;/h1&gt;

&lt;p&gt;Some use cases for polymorphic relations should now be obvious.&lt;/p&gt;

&lt;p&gt;A lot of Web 2.0 functionality naturally comes to mind. Likes, follows, comments, reactions, etc. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On a photo-sharing website, I want to be able to like photos but also comments on photos and maybe other users. &lt;/li&gt;
&lt;li&gt;On movie review site, I should be able to like movies but also reviews of movies as well as directors and actors. &lt;/li&gt;
&lt;li&gt;On a news website, I should be able to follow reporters but also topics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The possibilities are endless. &lt;/p&gt;

&lt;p&gt;In general: if you have a website about subject matter X, you will naturally want to enable user interactions with anything in that domain, and also with other users, and also with those other users' interactions. &lt;/p&gt;

&lt;p&gt;Each user will have interactions with lots of different kinds of things.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conceptual foundations
&lt;/h1&gt;

&lt;p&gt;Fortunately, Active Record makes this surprisingly simple.&lt;/p&gt;

&lt;p&gt;Before we get there, though, let's think about what we're asking for. &lt;/p&gt;

&lt;p&gt;In our hypothetical likes table, each row or like-instance belongs to exactly one likable, or thing that is liked. &lt;/p&gt;

&lt;p&gt;So we will need a column that tells us the id of the likable. Then we would also need some way of telling what kind of thing the likable is.  &lt;/p&gt;

&lt;p&gt;At this point, we could implement a separate likes table for reach kind of liked thing. Instead of just plain likes, we could have episodeLikes and showLikes and so on. &lt;/p&gt;

&lt;p&gt;That would allow us to use vanilla has-many and belongs-to relations. But at the cost of multiplying the number of tables, and therefore of migrations and models as well. Whenever we wanted to enable likes on a new kind of thing, we would have to create a whole new table for its likes as well. &lt;/p&gt;

&lt;p&gt;Not good. &lt;/p&gt;

&lt;p&gt;Alternatively, we could try map particular ids to particular things, so that odd-numbered foreign keys indicated shows and even-numbered indicated episodes.&lt;/p&gt;

&lt;p&gt;But this would meaning altering the logic by which ids are assigned. It would also make it difficult to add other likables without carefully rearranging the whole id-assignment logic.&lt;/p&gt;

&lt;p&gt;Or we could somehow tell the database to look for the likable using an additional column, something that indicated the type of the likable. That way, Active Record would know which of many tables look in as well as the record within that table.&lt;/p&gt;

&lt;p&gt;1) What kind of thing do you want?&lt;br&gt;
2) What is its id?&lt;/p&gt;

&lt;p&gt;Instead of a normal single-column foreign key, what we need conceptually is something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;likable_type
likable_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is that both columns together function like a normal foreign key in pointing us to a particular record that the like belongs to.&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementation
&lt;/h1&gt;

&lt;p&gt;Without further ado, let's start setting up a polymorphic association from likes to shows and episodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Add in a type column to the &lt;code&gt;belongs_to&lt;/code&gt; table
&lt;/h2&gt;

&lt;p&gt;As mentioned, likes needs an additional column beyond just foreign key. So we'll need to modify the db migration to add that in. Our migration will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateLikes &amp;lt; ActiveRecord::Migration[6.1]
  def change
    create_table :likes do |t|
      t.integer :user_id
      t.integer :likable_id
      t.string :likable_type
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If likes were only for shows, we could have include a &lt;code&gt;show_id&lt;/code&gt; foreign key. But since we are abstracting likes to be free from any particular liked thing, we refer to the foreign key as &lt;code&gt;likable_id&lt;/code&gt;. And since we still need to track what kind of thing is being liked, we add in a string column &lt;code&gt;likable_type&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use the &lt;code&gt;:polymorphic&lt;/code&gt; option for &lt;code&gt;belongs_to&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Each like still belongs to exactly one likable, whether an episode or show. However, we need to tell Active Record that likables can be drawn from different tables. &lt;/p&gt;

&lt;p&gt;To do this we simply add in an option in when we specify the &lt;code&gt;belongs_to&lt;/code&gt; relation in our Like model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Like &amp;lt; ActiveRecord::Base
    belongs_to :user
    belongs_to :likable, polymorphic: true
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Use the &lt;code&gt;:as&lt;/code&gt; option for &lt;code&gt;has_many&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Shows and episodes both have many likes. That part hasn't changed. We just need to specify that the likes for a particular show or episode should be found by looking in the &lt;code&gt;likable_id&lt;/code&gt; and &lt;code&gt;likable_type&lt;/code&gt; columns, as opposed to &lt;code&gt;show_id&lt;/code&gt; or &lt;code&gt;episode_id&lt;/code&gt; as in a typical association. &lt;/p&gt;

&lt;p&gt;Active Record makes this easy to do with the &lt;code&gt;:as&lt;/code&gt; option for &lt;code&gt;has_many&lt;/code&gt;, where we simply pass in the abstract type &lt;code&gt;:likable&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Show &amp;lt; ActiveRecord::Base
    has_many :likes, as: :likable
end

class Episode &amp;lt; ActiveRecord::Base
    has_many :likes, as: :likable
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! With a few simple options, we've implemented a polymorphic association in ActiveRecord. A like now belongs to exactly one likable, but that likable can be a show, an episode, or anything else we might need. &lt;/p&gt;

&lt;h1&gt;
  
  
  Working with polymorphic associations
&lt;/h1&gt;

&lt;p&gt;Let's take a quick look at how easy it is to work with polymorphic associations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating instances
&lt;/h2&gt;

&lt;p&gt;We can test-drive our polymorphic association by creating some seed data. &lt;/p&gt;

&lt;p&gt;The nice thing about Active Record is that it lets us pass in a hash of a user and likable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Like.create(user: User.first, likable: Episode.first)
#=&amp;gt;#&amp;lt;Like:0x00007fdd89fc46d0 id: 1, user_id: 1, likable_id: 1, likable_type: "Episode"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;likable_type&lt;/code&gt; column is filled in automatically with the appropriate string, along with the integer id.&lt;/p&gt;

&lt;p&gt;The cool thing is that we can do this, even though we didn't create a separate model for Likable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instance methods
&lt;/h2&gt;

&lt;p&gt;We can also call a &lt;code&gt;#likes&lt;/code&gt; instance method on a user to see an array of likes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.first.likes
#=&amp;gt; [#&amp;lt;Like:0x00007fdd89f7e450 id: 1, user_id: 1, likable_id: 1, likable_type: "Episode"&amp;gt;, #&amp;lt;Like:0x00007fdd89f7e0e0 id: 2, user_id: 1, likable_id: 1, likable_type: "Show"&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What about going in the other direction from a likable, like an episode to an array of users who have liked it?&lt;/p&gt;

&lt;p&gt;We can do that by adding a &lt;code&gt;has_many&lt;/code&gt; and passing &lt;code&gt;:likes&lt;/code&gt; to the &lt;code&gt;:through&lt;/code&gt; option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Episode &amp;lt; ActiveRecord::Base
    has_many :likes, as: :likable
    has_many :users, through: :likes
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can call a &lt;code&gt;#users&lt;/code&gt; method on an episode instance and see an array of users who have liked the episode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Episode.first.users
#=&amp;gt; [#&amp;lt;User:0x00007fdd89f2e2e8 id: 1, name: "Marion Batz", email: "reba@hand.co"&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, what if we wanted to get likables of a particular type for each user? &lt;/p&gt;

&lt;p&gt;We can do this quickly by adding one more line to our User model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ActiveRecord::Base
    has_many :likes
    has_many :liked_episodes, through: :likes, source: :likable, source_type: "Episode"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can call &lt;code&gt;#liked_episodes&lt;/code&gt; and Active Record will focus only on those likes with the specified &lt;code&gt;likable_type&lt;/code&gt; of "Episode".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User.first.liked_episodes
#=&amp;gt;[#&amp;lt;Episode:0x00007fdd9080c008 id: 1, num: 1, show_id: 1&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So without defining any new models, methods, or tables, we can establish polymorphic many-to-many relationships, with only a few optional parameters. Pretty cool!  &lt;/p&gt;

</description>
      <category>ui</category>
      <category>design</category>
      <category>ux</category>
      <category>website</category>
    </item>
    <item>
      <title>Interspersing arrays in Ruby</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Fri, 03 Feb 2023 22:00:44 +0000</pubDate>
      <link>https://dev.to/mattishida/interspersing-arrays-in-ruby-164k</link>
      <guid>https://dev.to/mattishida/interspersing-arrays-in-ruby-164k</guid>
      <description>&lt;p&gt;Ruby boasts an impressive set of built-in methods for working with arrays. That's great, but it can lead to some deep rabbit-holes when you expect to find a method that solves your problem and one isn't readily available. &lt;/p&gt;

&lt;p&gt;In this post, I'm going to describe my journey going down one such rabbit-hole as Ruby beginner. &lt;/p&gt;

&lt;p&gt;I'll touch on a number of array methods, do some benchmarking, and finish with an attempt at creating a custom enumerator.&lt;/p&gt;

&lt;h1&gt;
  
  
  Interspersing arrays
&lt;/h1&gt;

&lt;p&gt;The problem I was looking to solve is easy to state: how do you intersperse or pad a certain separator element between the elements of an array? &lt;/p&gt;

&lt;p&gt;With a string, this is easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;str = 'ruby'
str.split('').join('|')
# =&amp;gt; "r|u|b|y" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've easily inserted a separator character '|' between every pair of consecutive elements. We did so by splitting the original string into an array of individual characters, then chained a call to &lt;code&gt;#join&lt;/code&gt; which combines the elements back into a string, inserting its argument along the way. &lt;/p&gt;

&lt;p&gt;How do you do the same thing to arrays? (A simple use case is needing to print an array with a separator character between the elements. But it's also an interesting problem in its own right.)&lt;/p&gt;

&lt;p&gt;We would like to have a method that operates on an array and returns an a new array with the elements in the same order, just separated by a separator-element which we pass as a parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr = ['ruby', 'javascript', 'python', 'c']
arr.intersperse([0,1])
#=&amp;gt; ['ruby', [0,1], 'javascript', [0,1], 'python', [0,1], 'c'] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I felt sure that there must be a method doing exactly this out of the box.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generalizing the problem
&lt;/h1&gt;

&lt;p&gt;Let's stipulate that the solution to the problem should be capable of operating on any kind of array, with any kind of separator. The array can be nested to any level, as can the separator. Additionally, the separator may have the same value as one of the elements: we can't rule out that the separator is not also an element.&lt;/p&gt;

&lt;p&gt;And even though it's not strictly part of the problem as stated, we should also think about how to generalize the problem to different intervals. What if we wanted the separator every third element, or every fourth, or fifth? What if we want the gaps between separators to increase by one each time like so &lt;code&gt;[,sep,,sep,,,sep,,,,sep....]&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;In its full generality, I think of the problem as a kind of nested enumeration. You are enumerating through your original array while also enumerating through another array that determines your separator placement.&lt;/p&gt;

&lt;p&gt;But let's get back to the original problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  Some solutions
&lt;/h1&gt;

&lt;p&gt;Putting first things first, we can start with the simpler problem of interspersing a separator element between consecutive elements of an array. &lt;/p&gt;

&lt;p&gt;I dove into the Ruby docs. &lt;/p&gt;

&lt;p&gt;Here the wealth of array and enumerable methods was a bit of a red herring. There were so many that it was easy to believe that the perfect method was out there if I just kept digging. &lt;/p&gt;

&lt;p&gt;For all I know, it is still out there. But I pretty quickly turned to StackOverflow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/9422258/how-to-insert-a-new-element-in-between-all-elements-of-a-ruby-array" rel="noopener noreferrer"&gt;This thread&lt;/a&gt; was helpful insofar as it appears to confirm that  the one-stop, out-of-the-box method doesn't exist. &lt;/p&gt;

&lt;p&gt;It did offer a number of helpful ways to approach the problem. As of this writing, solutions including using &lt;code&gt;#flat_map&lt;/code&gt;, &lt;code&gt;#product&lt;/code&gt;, &lt;code&gt;#inject&lt;/code&gt;, &lt;code&gt;#each&lt;/code&gt;, and &lt;code&gt;#zip&lt;/code&gt;, with &lt;code&gt;#flat_map&lt;/code&gt; getting the most votes.&lt;/p&gt;

&lt;h1&gt;
  
  
  My own naive solution
&lt;/h1&gt;

&lt;p&gt;Lest you think that I am a slave to StackOverflow, I did try conjuring my own solution out of thin air.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
(0..2*arr.length-2).map {|i| i.even? arr[i/2] : sep}
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core idea is that our output array has the original elements at even numbered indices and the separator element at odd-numbered indices. The output array has length &lt;code&gt;2*arr.length-1&lt;/code&gt;, hence its last index is &lt;code&gt;2*arr.length-2&lt;/code&gt;. We simply need to iterate over the indices and pull in the appropriate value depending on whether &lt;code&gt;i&lt;/code&gt; is even or not. &lt;/p&gt;

&lt;h1&gt;
  
  
  Other one-line solutions
&lt;/h1&gt;

&lt;p&gt;The other solutions on StackOverflow fall basically into two families. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create &lt;code&gt;[elem, sep]&lt;/code&gt; sub-arrays, then flatten one level down to remove the nesting that was introduced.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an array, then iterate through the original array, shoveling in both the &lt;code&gt;elem&lt;/code&gt; and the separator as you go.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of these methods also require a penultimate step of removing the last element since arrays should not end with a separator. &lt;/p&gt;

&lt;p&gt;This is achieved using using the &lt;code&gt;...&lt;/code&gt; operator to construct a range of indices up to but excluding the last index, then using bracket notation to select all elements with index in the range. &lt;/p&gt;

&lt;h1&gt;
  
  
  Sub-array type solutions
&lt;/h1&gt;

&lt;p&gt;Let's dive into each family of solutions in a bit more detail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#flat_map
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
arr.flat_map {|elem| [elem, sep]}[0...-1]
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;#product
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
arr.product([sep]).flatten(1)[0...-1]
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;#zip
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
arr.zip([sep]*arr.length).flatten(1)[0...-1]
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Sub-array solutions: takeaways
&lt;/h1&gt;

&lt;p&gt;These three sub-array methods are all doing basically the same thing. In the context of our example &lt;code&gt;arr&lt;/code&gt;, they all pass through the intermediate step of creating an array of sub-arrays.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[3, "|"], [5, "|"], [7, "|"], [9, "|"]] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final step is to flatten down one level and lop of the final separator. This all happens explicitly in the &lt;code&gt;#product&lt;/code&gt; and &lt;code&gt;#zip&lt;/code&gt; methods, and under the hood in the &lt;code&gt;#flat_map&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;#product&lt;/code&gt; and &lt;code&gt;#zip&lt;/code&gt; methods are almost identical down to the syntax. The principal difference here is that product allows us to pass in a single element array as an argument, while we need to pass in a longer array to &lt;code&gt;#zip&lt;/code&gt;. How long exactly? It turns out it doesn't matter, so long as it contains at least as many separators we need in the final array. &lt;/p&gt;

&lt;p&gt;For example, passing in a MUCH longer array of separators does nothing to the final result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr.zip([sep]*100*arr.length)
#=&amp;gt; [[3, "|"], [5, "|"], [7, "|"], [9, "|"]] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My final takeaway is that while &lt;code&gt;#flat_map&lt;/code&gt; performs its flattening under the hood, it doesn't go overboard. It concatenates the results of the block but without calling flatten on those results first. So we can use &lt;code&gt;#flat_map&lt;/code&gt; even when our elements and separators are themselves nested.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nested_sep = [[sep]]
nested_arr = arr.map {|elem| [[elem]]}
nested_arr.flat_map {|elem| [elem, nested_sep]}
 =&amp;gt; [[[3]], [["*"]], [[5]], [["*"]], [[7]], [["*"]], [[9]], [["*"]]] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Shovel solutions
&lt;/h1&gt;

&lt;p&gt;Moving on to the second family of solutions, which involve iterating once through the array and using the shovel operator. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#inject (#reduce)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
arr.inject([]) {|memo, elem| memo &amp;lt;&amp;lt; elem &amp;lt;&amp;lt; sep}[0...-1]
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;#each
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9], "|"
memo = []
arr.each {|elem| memo &amp;lt;&amp;lt; elem &amp;lt;&amp;lt; sep}
memo[0...-1]
#=&amp;gt; [3, "|", 5, "|", 7, "|", 9] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both solutions in this family are doing roughly the same thing: iterating through and shoveling in both the element and the separator. With inject or reduce the accumulator variable memo is created inline, while the each method acts on an existing variable.&lt;/p&gt;

&lt;p&gt;The solutions in this family feel a little less clever and seem to garner less support on StackOverflow, but they are brutally efficient, as we'll see.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benchmarking
&lt;/h1&gt;

&lt;p&gt;So which of these solutions is best? We can use the &lt;code&gt;benchmark&lt;/code&gt; gem to do some basic benchmarking. &lt;/p&gt;

&lt;p&gt;Somewhat surprisingly, the shovel family of solutions seems to have significant performance benefits at scale. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj4jvpckopob9a0czm8z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxj4jvpckopob9a0czm8z.png" alt="Image description" width="477" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that for benchmarking purposes, I used an array with 10 million elements, each of which was an array of 3 single-digit integers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Adaptability
&lt;/h1&gt;

&lt;p&gt;Aside from raw performance, the other important question is which of the solutions can be adapted to inserting separators every three, four or five elements?&lt;/p&gt;

&lt;p&gt;With the sub-array family, this is pretty straightforward. We simply chain the &lt;code&gt;#each_slice&lt;/code&gt; method to the front and add a bit of destructuring in our block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9,11,13], "|"
arr.each_slice(2).flat_map {|elem| [*elem, sep]}[0...-1]
#=&amp;gt; [3, 5, "|", 7, 9, "|", 11, 13] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#each_slice&lt;/code&gt; methods creates an array of sub-arrays each with a passed-in length. To avoid an extra layer of nesting in the call to the flat_map block we destructure before adding in the separator element. &lt;/p&gt;

&lt;p&gt;For the shovel family, we would need to add some kind of check on the index to determine when we should shovel in the separator. I used the modulo operator &lt;code&gt;%&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr, sep = [3,5,7,9,11,13], "|"
memo = []
arr.each.with_index do |elem, idx| 
  if idx%2 == 1
    memo &amp;lt;&amp;lt; elem &amp;lt;&amp;lt; sep
  else 
    memo &amp;lt;&amp;lt; elem
  end
end
arr.length%2==0 ? memo[0...-1] : memo
# =&amp;gt; [3, 5, "|", 7, 9, "|", 11, 13] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a bit more awkward as it involves more calculation and may be more prone to off-by-one errors. I also needed to do an extra check at the end to make sure the return vale does not end in a separator.&lt;/p&gt;

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

&lt;p&gt;While the sub-array solutions are slightly less performant on large arrays, they generalize more easily. It's hard to say that there is a single approach that works best in all situations, for all use cases. But I suppose this is nothing new to most programmers. &lt;/p&gt;

&lt;h1&gt;
  
  
  Postscript: a custom enumerator
&lt;/h1&gt;

&lt;p&gt;As a postscript, here is my attempt to build a custom enumerator. Why would we want a custom enumerator? I suppose one reason is that we might require an enumerator outside of a context where we're working with arrays. It generalizes the problem to a further level, beyond the array class.&lt;/p&gt;

&lt;p&gt;Here then is my amateur-ish attempt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def nested_enum (arr, sep, every)
    Enumerator.new do |y| 
        main = arr.to_enum
        internal = Enumerator.produce(1) {|x| (x+1)% every}

        a = main.next
        b = internal.next
      loop do
        if b == 0 
            y &amp;lt;&amp;lt; sep
        else 
            y &amp;lt;&amp;lt; a
            a = main.next
        end
        b = internal.next
      end
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method will return an enumerator object. When &lt;code&gt;.next&lt;/code&gt; is called on it, it will yield from the &lt;code&gt;main&lt;/code&gt; enumerator, except at regular intervals when it will instead yield value &lt;code&gt;sep&lt;/code&gt; according to the value of the &lt;code&gt;internal&lt;/code&gt; enumerator. It will then go back to yielding from the main without missing a beat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myEnum = nested_enum((0..8), 'hi', 3).to_a
#=&amp;gt;[0, 1, "hi", 2, 3, "hi", 4, 5, "hi", 6, 7, "hi", 8]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also considered implementing this using a counter variable instead of an internal enumerator, even though I like the idea of drawing from two enumerators in one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def nested_enum_counter (arr, sep, every)
    Enumerator.new do |y| 
        main = arr.to_enum
        #internal = Enumerator.produce(1) {|x| (x+1)% every}

        a = main.next
        b = 1
      loop do
        if b % every == 0 
            y &amp;lt;&amp;lt; sep
        else 
            y &amp;lt;&amp;lt; a
            a = main.next
        end
        b += 1
      end
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I benchmarked the custom enumerator solution, I found it was actually significantly less performant than the others discussed above. So I would say that the problem of interspersing arrays in Ruby is still to be completely solved, at least by yours truly.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Thinking functionally about React components</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Fri, 20 Jan 2023 19:39:01 +0000</pubDate>
      <link>https://dev.to/mattishida/thinking-functionally-about-react-components-3270</link>
      <guid>https://dev.to/mattishida/thinking-functionally-about-react-components-3270</guid>
      <description>&lt;p&gt;Learning React is much easier when you can connect the unique syntax to something you already know. In this post, I'm going to highlight a few ways in which it helps to have a mental model of React components as JavaScript functions.&lt;/p&gt;

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

&lt;p&gt;React is JavaScript library that allows you to write an enhanced HTML-style markup, known as JSX, directly within JavaScript files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;Header /&amp;gt;
  &amp;lt;ContentContainer /&amp;gt;
  &amp;lt;Form /&amp;gt;
&amp;lt;div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How is it "enhanced"? Well, in many ways. But at the level of syntax, which is my focus here,  you are able to define and use custom tags like &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;ContentContainer /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;CustomerInputForm /&amp;gt;&lt;/code&gt; in addition to &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;, and all the rest. These "custom" tags render React components to the DOM analogous to how normal HTML tags render HTML elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  React as HTML
&lt;/h2&gt;

&lt;p&gt;This suggests a simple mental model of React components as HTML elements or maybe 'HTML++'.&lt;/p&gt;

&lt;p&gt;That certainly seems to have been part of the inspiration for React. Indeed, someone who knew nothing about React could look at some JSX and get the idea that different entities are being rendered to the page in something like the way HTML elements are rendered.&lt;/p&gt;

&lt;p&gt;But I hope to convince you that React components are better thought of as JavaScript functions, not HTML elements. This helps to make a number of React features more intuitive. &lt;/p&gt;

&lt;h2&gt;
  
  
  Starting to see "functionally"
&lt;/h2&gt;

&lt;p&gt;Unfortunately, JavaScript makes this mental leap a tad difficult.&lt;/p&gt;

&lt;p&gt;In Javascript, arguments are passed to functions by position, not name. When invoking a function, arguments must be passed in the order of the parameters in the original function definition. Order matters. The function knows what do with each argument because of where it appears in the invocation.&lt;/p&gt;

&lt;p&gt;But in other languages, arguments can be with the name of the parameter. Then the function knows what to do with an argument because of the name it is passed with.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function greetUser(greeting, user){
   console.log(`${greeting}, ${user}!`)
}

greetUser('hello', 'Sasha') // unnamed arguments
greetUser(greeting='hello', user='Sasha') // named arguments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is this important? &lt;/p&gt;

&lt;p&gt;Because data or 'props' can be passed into React components using something like the HTML attribute syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;CardComponent name='Sasha' role='director' /&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you've seen functions invoked with named parameters, this is going to look a lot like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cardFunction(name='Sasha', role='director')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It becomes easy to see an instance of a React component as a function call. Syntactically, all we've done is change up the 'punctuation' a bit, switching out angle brackets for parentheses and omitting a comma. &lt;/p&gt;

&lt;p&gt;But if you're new to programming and you've never seen function invocations with named arguments, this might be less intuitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thinking functionally
&lt;/h2&gt;

&lt;p&gt;Once we're able to consistently see React components as functions, we can start to think of them as functions. Functions can serve as our base paradigm for understanding and remembering how to work with components.&lt;/p&gt;

&lt;p&gt;Here are some ways in which this paradigm or mental model is helpful:&lt;/p&gt;

&lt;h3&gt;
  
  
  0: Component declaration syntax as function declaration syntax
&lt;/h3&gt;

&lt;p&gt;The most obvious way in which it helps to think of components as functions is that they are declared as functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'

function MyForm(){
  return (
     &amp;lt;div&amp;gt;{/*Vanilla HTML or JSX referencing other 
         components*/}
     &amp;lt;/div&amp;gt;
  )
}
export default MyForm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are obviously using the syntax of normal JavaScript function declaration, with two slight twists: we've capitalized the first letter of the function name, and we're returning a single block of JSX.&lt;/p&gt;

&lt;p&gt;Ok, this is a kind of trivial case. Just because something is defined like a function doesn't mean it behaves like a function. But it helps get us off on the right foot.  &lt;/p&gt;

&lt;h3&gt;
  
  
  1: Downward data flow as function scope
&lt;/h3&gt;

&lt;p&gt;In React, data or 'props' flow downward from parent components to the child components nested with them. Any variables contained in the child have to already be present in the parent.  &lt;/p&gt;

&lt;p&gt;If you model components as HTML elements, this is a bit counterintuitive. When you think of &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; elements nested within a &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, the parent doesn't know anything about the &lt;code&gt;textContent&lt;/code&gt; of the children. Data flow is more bottom-up.&lt;/p&gt;

&lt;p&gt;But let's think functionally for a second. If I have a child function nested within a parent function, any variables that the child has access to have be in the scope of the parent. The child gets its context--i.e. its data--from the parent.&lt;/p&gt;

&lt;p&gt;Thinking of components as functions makes downward flow intuitive in a way that thinking of them as HTML elements does not.&lt;/p&gt;

&lt;h3&gt;
  
  
  2: Prop keys as parameter names
&lt;/h3&gt;

&lt;p&gt;One of the surprising things about React components is how reusable they can be. Since we can pass in event handler functions, we can make the same React component perform different actions depending on what sort of handler we pass in. Clicking on the component might delete something or add something or display an alert. It is all up to the handler that is passed in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;MyCard onClickHandler={handleDeleteItem} /&amp;gt;
&amp;lt;MyCard onClickHandler={handleAddItem} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might seem surprising the first time you see it.&lt;/p&gt;

&lt;p&gt;But if you model components as functions and props as parameters, it should be a little less surprising. It would be more surprising if you couldn't do this.&lt;/p&gt;

&lt;p&gt;The code above should be no more surprising than the below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myFunction(callback){...}

myFunction(cb1)
myFunction(cb2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just as we can pass different arguments to the same parameter, we can pass different functions as the same prop and have them executed in response to the same event in the same component. &lt;/p&gt;

&lt;h3&gt;
  
  
  3: Default values for props
&lt;/h3&gt;

&lt;p&gt;Did you know you can set a default value for a prop that will be used in the event no value is explicitly passed to the component?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MyComponent({ name, image = [some URL] }) {
 ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe you knew it but it seemed like quirk of React, a factoid taking up space in your brain? &lt;/p&gt;

&lt;p&gt;If you model components as functions, this feature will seem natural. After all, function parameters in vanilla JavaScript can be given default values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function greetUser(greeting='Hello', name){
  console.log(`${greeting}, ${user}!`)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if components are like functions and props are like parameters, it makes perfect sense that we are able to set default values for props. &lt;/p&gt;

&lt;h3&gt;
  
  
  4: Inverse data flow
&lt;/h3&gt;

&lt;p&gt;Inverse data flow is one of the biggest stumbling blocks in picking up React. Downward data flow is the norm, but it sometimes happens that a variable passed down from parent to a child component is then modified in the child, after which the parent needs access to that modified state.&lt;/p&gt;

&lt;p&gt;In React, this is done by passing a callback function as a prop from parent to child. This callback function essentially accesses the modified value in the child and assigns it to the correct variable in the parent.&lt;/p&gt;

&lt;p&gt;OK. When I first learned React, this feature seemed very arbitrary and ad hoc. I couldn't connect it to anything that I had already encountered. It made sense as a feature of a closed React universe but not as something more general. Presumably React has a lot of sophisticated machinery under the hood, so why achieve inverse data flow with a callback?&lt;/p&gt;

&lt;p&gt;Then I realized that you would do basically the same thing if for some reason you had nested JavaScript functions and needed to extract a value from within the child up to the parent. &lt;/p&gt;

&lt;p&gt;Here's a somewhat contrived example that still makes the point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function findLength(length){
  length=Math.floor(Math.random()*100)
  console.log(`from findLength: length=${length}`)
  return `JSX from findLength`
}

function findMeasurements(){
  const width = Math.floor(Math.random()*100)
  let length
  findLength(length)
  console.log(`from findMeasurements: length=${length}`)
  return 'JSX from findMeasurements'
}

findMeasurements() //=&amp;gt; from findLength: length=69 
                   //from findMeasurements: length=undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have &lt;code&gt;findLength&lt;/code&gt; function that generates a random length. It's using &lt;code&gt;Math.random()&lt;/code&gt;, but this could stand in for some complicated process or maybe a user interaction. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;findLength&lt;/code&gt; is called within a parent function &lt;code&gt;findMeasurements&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The question now is how we could get the value of &lt;code&gt;length&lt;/code&gt; up to &lt;code&gt;findMeasurements&lt;/code&gt; so that it can be logged in that context. &lt;code&gt;findLength&lt;/code&gt; determines the value of the &lt;code&gt;length&lt;/code&gt; variable as side effect, but it doesn't return it, so it is confined to the context of &lt;code&gt;findLength&lt;/code&gt; and can't be accessed by &lt;code&gt;findMeasurements&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The answer is that we could define and pass a setter function within &lt;code&gt;findMeasurements&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function findLength(length, lengthSetter){
  length=Math.floor(Math.random()*100)
  lengthSetter(length)
  console.log(`from findLength: length=${length}`)
  return `JSX from findLength`
}

function findMeasurements(){
  const width = Math.floor(Math.random()*100)
  let length

  function lengthSetter(value){
    length=value
  }
  findLength(length, lengthSetter)
  console.log(`from findMeasurements: length=${length}`)
  return 'JSX from findMeasurements'
}

findMeasurements() //=&amp;gt; from findLength: length=29
                   //from findMeasurements: length=29
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've essentially just recreated a feature of React in an entirely non-React context. React's use of callback functions to achieve inverse data flow is really no different from normal JavaScript functions would do (if they ever needed to)!&lt;/p&gt;

&lt;p&gt;What appeared to be a strange, ad hoc feature fits nicely into our broader mental model of JavaScript functions.&lt;/p&gt;

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

&lt;p&gt;However React components are implemented under the hood, my aim here has been to show that 'above the hood' they behave very much like JavaScript functions. We don't need to expend mental resources memorizing various React-specific features if we can see them as an extension of something we already know. &lt;/p&gt;

&lt;p&gt;What else? The beauty of patterns and analogies is that they are open-ended. Once you have identified a few similarities, it's natural to start to look for others and deepen our understanding even further. &lt;/p&gt;

&lt;p&gt;In what other ways does it pay to understand React components as functions? &lt;/p&gt;

</description>
      <category>gratitude</category>
      <category>community</category>
    </item>
    <item>
      <title>Closure and event listeners</title>
      <dc:creator>mattIshida</dc:creator>
      <pubDate>Fri, 06 Jan 2023 21:40:14 +0000</pubDate>
      <link>https://dev.to/mattishida/closure-and-event-listeners-1fn3</link>
      <guid>https://dev.to/mattishida/closure-and-event-listeners-1fn3</guid>
      <description>&lt;p&gt;Closure is notorious as one of the hardest concepts for Javascript beginners to pick up. That would be fine if it surfaced only rarely or in advanced applications. But closure plays a huge (and under-appreciated) role in Web Development 101. If you've ever added an event listener to handle a button click or a form submission like so: &lt;code&gt;myElement.addEventListener('click', callbackFunction)&lt;/code&gt;, you've likely been leveraging the power of closure.&lt;/p&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing closure
&lt;/h2&gt;

&lt;p&gt;Closure is a hidden superpower of functions in Javascript and other programming languages. When thinking about closure, the mantra that I repeat to myself over and over again is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Functions retain access to variables in the context in which they were created.&lt;br&gt;
Functions retain access to variables in the context in which they were created.&lt;br&gt;
Functions retain access to variables in the context in which they were created.&lt;br&gt;
...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Set aside the technical details for a second. More on those to come. One of the biggest practical takeaways, especially for the budding developer, is that functions can, if created in the right context, access data that might seem "lost." &lt;em&gt;You&lt;/em&gt; may have neglected to store a piece of data by assigning it to a global variable, but it's possible that one of your functions did not.&lt;/p&gt;

&lt;p&gt;The killer use case for this in basic web development is achieving front-end persistence without a lot of awkward global variables. But first let's go deeper into what closure is.&lt;/p&gt;

&lt;h2&gt;
  
  
  A non-web example of closure
&lt;/h2&gt;

&lt;p&gt;A classic simple illustration of closure begins with function that returns another function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let count = 0;
function outer(a){
  function inner(){
    count++;
    console.log(count)
    return a * count;
  }
  return inner;
}
const ourFunction = outer(5)
ourFunction() // =&amp;gt;1
ourFunction() // =&amp;gt;2
ourFunction() // =&amp;gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are defining a function &lt;code&gt;outer&lt;/code&gt; that itself defines a function called &lt;code&gt;inner&lt;/code&gt; and returns it. &lt;code&gt;inner&lt;/code&gt; increments the global variable &lt;code&gt;count&lt;/code&gt;, console.logs it, multiplies it by the value of the parameter &lt;code&gt;a&lt;/code&gt;, and finally returns that result. &lt;/p&gt;

&lt;p&gt;When we call &lt;code&gt;outer&lt;/code&gt; with the argument 5, it defines a function in the global scope named &lt;code&gt;ourFunction&lt;/code&gt;. So &lt;code&gt;ourFunction&lt;/code&gt; returns the next multiple of 5 each time it is called. Moreover, repeatedly calling &lt;code&gt;ourFunction&lt;/code&gt; will log the value of &lt;code&gt;count&lt;/code&gt; incremented by 1 each time. So &lt;code&gt;ourFunction&lt;/code&gt; seems to be doing a useful service not only of counting by five but also of tracking the number of times it has been invoked.&lt;/p&gt;

&lt;p&gt;All of this should be relatively straightforward. Since &lt;code&gt;count&lt;/code&gt; is a global variable, it can be accessed from inside &lt;code&gt;outer&lt;/code&gt; and for that matter from inside &lt;code&gt;inner&lt;/code&gt; as well!&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;count&lt;/code&gt; is maybe a little &lt;em&gt;too&lt;/em&gt; accessible. What if we had some friends who wanted to use &lt;code&gt;outer&lt;/code&gt; to do their own counting by 7s. We could try something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let count = 0;
function outer(a){
  function inner(){
    count++;
    console.log(count)
    return a * count;
  }
  return inner;
}
const ourFunction = outer(5)
ourFunction() // =&amp;gt;1
ourFunction() // =&amp;gt;2
ourFunction() // =&amp;gt;3

const theirFunction = outer(7)
theirFunction() // =&amp;gt;4
theirFunction() // =&amp;gt;5
theirFunction() // =&amp;gt;6

ourFunction() // =&amp;gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The global variable &lt;code&gt;count&lt;/code&gt; now gets incremented by both &lt;code&gt;ourFunction&lt;/code&gt; and &lt;code&gt;theirFunction&lt;/code&gt;. The first time &lt;code&gt;theirFunction&lt;/code&gt; gets called it logs 4 and returns 28. We have lost the desirable feature of counting up smoothly by 5s or 7s and of tracking the number of times each specific function was invoked.&lt;/p&gt;

&lt;p&gt;What we would like to have is a &lt;code&gt;count&lt;/code&gt; variable specific to &lt;code&gt;ourFunction&lt;/code&gt; and another &lt;code&gt;count&lt;/code&gt; variable specific to &lt;code&gt;theirFunction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could define two global variables, &lt;code&gt;ourCount&lt;/code&gt; and &lt;code&gt;theirCount&lt;/code&gt;. But what if we wanted to count by 9s, 11s, 13s, and so on? We could create a new global variable each time, but then we could wind up with hundreds or thousands. &lt;/p&gt;

&lt;p&gt;What to do?&lt;/p&gt;

&lt;p&gt;We know from Javascript 101 that invoking a function creates its own execution context. Variables defined in that context are not accessible once the function returns a value: if you declare &lt;code&gt;myVar&lt;/code&gt; within a function, you don't then get to access &lt;code&gt;myVar&lt;/code&gt; outside that function. But this seems to deepen the mystery. Shouldn't a variable be either global (which won't work for us) or else confined to fleeting execution context where we can't get to it?&lt;/p&gt;

&lt;p&gt;Let's go back to our mantra:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Functions retain access to variables in the context in which they were created.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unpacking this, we know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ourFunction&lt;/code&gt; retains access to variables in the context in which it was created. &lt;/li&gt;
&lt;li&gt;It was created in the execution context of the function &lt;code&gt;outer&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;So any variable declared in the scope of &lt;code&gt;outer&lt;/code&gt; would be accessible to &lt;code&gt;ourFunction&lt;/code&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wouldn't that same variable be accessible to &lt;code&gt;theirFunction&lt;/code&gt; as well? Well, no, not the same variable, but a similar variable with the same name, because each time &lt;code&gt;outer&lt;/code&gt; is invoked it defines a new execution and &lt;code&gt;count&lt;/code&gt; is declared anew in that context and functions declared in the same context would have access to it! This seems to be exactly what we want. &lt;/p&gt;

&lt;p&gt;This line of thought suggests that we simply declare &lt;code&gt;count&lt;/code&gt; inside &lt;code&gt;outer&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function outer(a){
  let count = 0;
  function inner(){
    count++;
    console.log(count)
    return a * count;
  }
  return inner;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And indeed this gives us what we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ourFunction = outer(5)
ourFunction() // =&amp;gt;1
ourFunction() // =&amp;gt;2
ourFunction() // =&amp;gt;3

const theirFunction = outer(7)
theirFunction() // =&amp;gt;1
theirFunction() // =&amp;gt;2
theirFunction() // =&amp;gt;3

ourFunction() // =&amp;gt; 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each time we invoke &lt;code&gt;outer&lt;/code&gt; to create a function, we are also creating a locally-scoped &lt;code&gt;count&lt;/code&gt; variable that &lt;code&gt;inner&lt;/code&gt;, which is created in the same context, can access. We are creating a &lt;code&gt;count&lt;/code&gt; variable that is &lt;em&gt;enclosed&lt;/em&gt; within that function. &lt;/p&gt;

&lt;h2&gt;
  
  
  Achieving front-end persistence
&lt;/h2&gt;

&lt;p&gt;This may all seem like a curiosity or a programming exercise. How often do we actually define functions within functions? &lt;/p&gt;

&lt;p&gt;It turns out to be surprisingly common. Any time you have a set of elements on a website--images, buttons, names in a list--and want to add the same functionality to each one, you are like to define a function that iterates over each element. And within that function you are like to call the &lt;code&gt;addEventListener&lt;/code&gt; method which itself takes a function, the so-called callback, has an argument. So for each element, you are declaring a function to be executed in response to a certain event, and you are doing that from within another function. Exactly the situation where closure can shine!&lt;/p&gt;

&lt;p&gt;For example, what if you wanted to be able to track clicks or other events the same we tracked the number of times &lt;code&gt;ourFunction&lt;/code&gt; was invoked? It should be no surprise that closure can do the job. &lt;/p&gt;

&lt;h2&gt;
  
  
  A simple voting app
&lt;/h2&gt;

&lt;p&gt;To make this more concrete, let's consider a simple website for tracking votes (clicks). &lt;/p&gt;

&lt;p&gt;Note: We're dealing with front-end persistence only here, so "tracking" for our purposes means tracking within a single session. Any data will disappear when the page reloads.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnktu72y2pwcf45rgvmq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnktu72y2pwcf45rgvmq.png" alt="Color voting website with lightpink background" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here the user can select three color options for which to vote as many times as they wish. &lt;/p&gt;

&lt;p&gt;When you click the lightpink button, the background changes to lightpink and you can click the voting button to vote for lightpink. A counter of the current votes is displayed.&lt;/p&gt;

&lt;p&gt;Similarly, when you click the lightblue button, the same thing happens. The background changes and you can now vote for lightblue and see a count of votes for lightblue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhjulqottbpjzg6mrc97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhjulqottbpjzg6mrc97.png" alt="Color voting website with lightblue background" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ditto for lightgreen. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd0fpa57o9axu5oyscde.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd0fpa57o9axu5oyscde.png" alt="Color voting website with lightgreen background" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the question: how do we get the vote counts for each color to persist such that votes for each color are counted accurately no matter how many times we switch between colors, voting as we wish for each? Three votes for lightgreen should stay three votes when I switch to light green, no matter how many times I vote for lightpink or lightblue in the interim.&lt;/p&gt;

&lt;p&gt;Answer: closure. &lt;/p&gt;

&lt;p&gt;The problem is really not so different from tracking invocations of &lt;code&gt;ourFunction&lt;/code&gt; and &lt;code&gt;theirFunction&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/mattIshida/closure-event-listeners" rel="noopener noreferrer"&gt;Code for this section is on github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First we can create the bare bones of the voting website by iterating over an array of colors and calling a function on each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const colors = ['lightpink', 'lightblue', 'lightgreen']
colors.forEach(addColorToDOM)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We simply need to define the &lt;code&gt;addColorToDOM&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The function needs to do three things: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add each color button to the page&lt;/li&gt;
&lt;li&gt;Add functionality that changes the background color and displays votes in response to a click on the button&lt;/li&gt;
&lt;li&gt;Counts votes (i.e. clicks on the voting button) correctly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first item is straightforward. For each color we simply generate a new DOM element, set its text content, and append it to the correct HTML element, which we've assigned to the variable &lt;code&gt;colorList&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DOM selectors
const colorList = document.querySelector('#color-list')

// Render functions
function addColorToDOM(color){
    const choiceButton = document.createElement('button')
    choiceButton.textContent = color
    colorList.append(choiceButton)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second is a bit more complicated but still pretty easy. We simply add a click event listener to our &lt;code&gt;choiceButton&lt;/code&gt; element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DOM selectors
const colorList = document.querySelector('#color-list')

// Render functions
function addColorToDOM(color){
    const choiceButton = document.createElement('button')
    choiceButton.textContent = color
    colorList.append(choiceButton)

    choiceButton.addEventListener('click', () =&amp;gt; {
        document.body.style.backgroundColor = color
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice.&lt;/p&gt;

&lt;p&gt;The click also needs to display the votes, so let's go ahead and declare a &lt;code&gt;voteCount&lt;/code&gt; variable initialized to 0 and inject that content into the appropriate DOM element as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DOM selectors
const colorList = document.querySelector('#color-list')
const votes = document.querySelector('#votes')

// Global variables
let voteCount = 0

// Render functions
function addColorToDOM(color){
    const choiceButton = document.createElement('button')
    choiceButton.textContent = color
    colorList.append(choiceButton)

    choiceButton.addEventListener('click', () =&amp;gt; {
        document.body.style.backgroundColor = color
        votes.textContent = `Current votes for ${color}: 
         ${voteCount}`
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, so good. Now we have only have the third task of figuring out how to set &lt;code&gt;voteCount&lt;/code&gt; correctly for each color.&lt;/p&gt;

&lt;p&gt;As a first step, observe that each color should listen for clicks on the vote button, but only count votes if that color is the currently selected color. So we'll need to add an event listener on the &lt;code&gt;voteButton&lt;/code&gt; element, plus a variable to track which color is currently selected&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DOM selectors
const colorList = document.querySelector('#color-list')
const votes = document.querySelector('#votes')
const voteButton = document.querySelector('#vote-btn')

// Global variables
let voteCount = 0
let currentSelection

// Render functions
function addColorToDOM(color){
    const choiceButton = document.createElement('button')
    choiceButton.textContent = color
    colorList.append(choiceButton)

    choiceButton.addEventListener('click', () =&amp;gt; {
        currentSelection = color
        document.body.style.backgroundColor = color
        votes.textContent = `Current votes for ${color}: 
         ${voteCount}`
    })

    voteButton.addEventListener('click', ()=&amp;gt;{
        if(currentSelection === color) {
            voteCount++;
            votes.textContent = `Current votes for ${color}: 
            ${voteCount}`
        }
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need to modify the &lt;code&gt;choiceButton&lt;/code&gt; callback to update the &lt;code&gt;currentSelection&lt;/code&gt; variable. I've gone ahead and included those modifications in the code above as well. &lt;/p&gt;

&lt;p&gt;OK. It looks like we have all the pieces we'll need. Let's go ahead and test. &lt;/p&gt;

&lt;p&gt;I can easily add votes for lightpink.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filmgm4wwgz2qsq51c5y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filmgm4wwgz2qsq51c5y8.png" alt="votes for lightpink" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But as soon as I select lightblue the counter starts where lightpink left off and increments from there. FAIL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Forxgixf32zrx0iio0n9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Forxgixf32zrx0iio0n9v.png" alt="incorrect votes for lightblue" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hmm... we set up event listeners on each button with callbacks that increment the same global variable &lt;code&gt;voteCount&lt;/code&gt;. What we actually need is a &lt;code&gt;voteCount&lt;/code&gt; specific to each.&lt;/p&gt;

&lt;p&gt;This is exactly the situation we faced with &lt;code&gt;ourFunction&lt;/code&gt; and &lt;code&gt;theirFunction&lt;/code&gt;. There too we had a &lt;code&gt;count&lt;/code&gt; variable that both functions could access, and we needed a variable that was specific to each. We solved the problem by declaring the &lt;code&gt;count&lt;/code&gt; variable in the unique execution context where each function was created and let closure do its thing.  &lt;/p&gt;

&lt;p&gt;Let's do the same here. We simply move the declaration of &lt;code&gt;voteCount&lt;/code&gt; from the global context to inside the &lt;code&gt;addcolorToDOM&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// DOM selectors
const colorList = document.querySelector('#color-list')
const votes = document.querySelector('#votes')
const voteButton = document.querySelector('#vote-btn')

// Global variables
let currentSelection

// Render functions
function addColorToDOM(color){
    const choiceButton = document.createElement('button')
    choiceButton.textContent = color
    colorList.append(choiceButton)

    let voteCount = 0

    choiceButton.addEventListener('click', () =&amp;gt; {
        currentSelection = color
        document.body.style.backgroundColor = color
        votes.textContent = `Current votes for ${color}: 
         ${voteCount}`
    })

    voteButton.addEventListener('click', ()=&amp;gt;{
        if(currentSelection === color) {
            voteCount++;
            votes.textContent = `Current votes for ${color}: 
            ${voteCount}`
        }
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when addColorToDom gets called on a color, it creates a new execution context and a new voteCount variable. And we know from our mantra&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Functions retain access to variables in the context in which they were created.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;that the callback functions created in the same execution context will retain access to those variables, even when the execution context goes away. &lt;/p&gt;

&lt;p&gt;When we test out the solution, it does indeed work to count votes for each color and persist them when you switch back and forth. &lt;/p&gt;

&lt;p&gt;I can start logging votes for lightpink:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr4dxtd1v9k0rohl1xsl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr4dxtd1v9k0rohl1xsl.png" alt="persisting votes for lightpink" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Switch to lightblue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0a2aecookgu4fafwi1bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0a2aecookgu4fafwi1bx.png" alt="persisting votes for lightpink" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And to lightgreen: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbl88hik1c11ppofjeur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbl88hik1c11ppofjeur.png" alt="persisting votes for lightpink" width="609" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vote counts are accurate and remain so even when I toggle back and forth to my heart's content. &lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;We were able to achieve front-end persistence without any data structure that explicitly logged votes for each of the three colors. Instead, we were able to enclose a color-specific &lt;code&gt;voteCount&lt;/code&gt; variable within each callback function. Every time the callback function got invoked it retained access to its own &lt;code&gt;voteCount&lt;/code&gt; variable. &lt;/p&gt;

&lt;p&gt;In fact the connection between closure and event listeners goes even deeper than what I've discussed here, but I'll leave that for another post.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
