<?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: Daniel Hintz</title>
    <description>The latest articles on DEV Community by Daniel Hintz (@dhintz89).</description>
    <link>https://dev.to/dhintz89</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%2F448927%2F36173d07-d76f-4c0e-9022-f21aee1b4b85.jpeg</url>
      <title>DEV Community: Daniel Hintz</title>
      <link>https://dev.to/dhintz89</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhintz89"/>
    <language>en</language>
    <item>
      <title>Exploring CSS: Micro-frameworks (Tailwind)</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Thu, 04 Feb 2021 00:34:43 +0000</pubDate>
      <link>https://dev.to/dhintz89/exploring-css-micro-frameworks-tailwind-2nh2</link>
      <guid>https://dev.to/dhintz89/exploring-css-micro-frameworks-tailwind-2nh2</guid>
      <description>&lt;p&gt;Next up in this series is trying out &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;, another framework.  I've heard a lot about how great Tailwind is, so I've really wanted to check it out for quite some time, what better time than now?  Tailwind is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A utility-first CSS framework packed with classes like &lt;code&gt;flex&lt;/code&gt;, &lt;code&gt;pt-4&lt;/code&gt;, &lt;code&gt;text-center&lt;/code&gt; and &lt;code&gt;rotate-90&lt;/code&gt; that can be composed to build any design, directly in your markup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a lot more to this framework than there was with Plume, so just know that I'm only scratching the surface at this point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's To Like
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Documentation
&lt;/h4&gt;

&lt;p&gt;My first thought when I looked at the documentation was "Wow, there's a LOT more to unpack here than there was with Plume!" but the good news is that the documentation is top-notch.  Not only does it do an excellent job of walking through how to use Tailwind, but it also contains instructions for related topics, like what is a pre-processor or how to build JavaScript components.&lt;/p&gt;

&lt;h4&gt;
  
  
  Set Up
&lt;/h4&gt;

&lt;p&gt;There are a couple of options for setting up Tailwind, and the documentation does a great job of talking you through not only &lt;em&gt;how&lt;/em&gt; to set it up with each method, but also &lt;em&gt;why&lt;/em&gt; you might want to use each method.  The easiest way is through a CDN.  All you have to do is include the link in your HTML and you're done.  Nothing to install or download.  However; the documentation warns against this as you lose a lot of the best features.  The recommended method is to install Tailwind as a PostCSS plugin, but I didn't go this route, mostly because I haven't gotten to exploring preprocessors yet - one thing at a time.  The last option is to use NPX to install Tailwind into your project as a CSS file: &lt;code&gt;npx tailwindcss-cli@latest build -o tailwind.css&lt;/code&gt;.  This is the route I took and, as a bonus, it is pretty close to what I did with Plume.&lt;/p&gt;

&lt;h4&gt;
  
  
  Utilities &amp;amp; Components
&lt;/h4&gt;

&lt;p&gt;This is where Tailwind really shines.  Where Plume is awesome for quickly setting up the basic components across your site, but not great at customizing individual elements, Tailwind is just the opposite.  There are hundreds of options in Tailwind, and they are all applied to the individual element, rather than making broad strokes across the site. As well, they are designed very tactically, meaning that each option only does one thing and can be chained with other options to get to the full effect that you are going for.  This means that, if I know I want to do something like create a flex-box that is centered in the page, all I have to do is look at the documentation for each "piece" of the formatting (display, sizing, spacing, and background), then just go down the list of options and copy/paste the class that gives the effect I want.&lt;/p&gt;

&lt;p&gt;Additionally, Tailwind gives you some pretty great pre-made components for free!  I particularly like the select and dropdown menus.  You'll generally need to build your own components using the provided utilities; however, unless you pay for Tailwind's premium content.&lt;/p&gt;

&lt;h4&gt;
  
  
  Customization
&lt;/h4&gt;

&lt;p&gt;Tailwind allows you to customize everything and create a very detailed "theme" for your site styling.  This goes well beyond what Plume can do, but is also a much heavier effort.  Although it doesn't seem too bad to customize, and the documentation does a great job of walking you through it, I decided to see how far I could get without doing any customization, so it's outside the scope of this article.  One really cool thing I did see; however, is that you can customize on several "layers" to help you avoid specificity clashes!&lt;/p&gt;

&lt;h4&gt;
  
  
  Component Extraction and Abstraction
&lt;/h4&gt;

&lt;p&gt;A major drawback of Tailwind is that there is a &lt;strong&gt;LOT&lt;/strong&gt; of duplicated code in your HTML (more on this below).  Fortunately, this can be avoided by extracting common components or abstracting the styles using Tailwind's &lt;code&gt;@apply&lt;/code&gt; feature.  This either requires very thoughtful planning, or a retro-active approach (after you've finished, go back and find/abstract your more common components), the latter being not so ideal.  But I imagine once I've used it a few times and I'm more familiar I'll have a pretty good idea of what I'll want to abstract away before even getting started.  Unfortunately, when I tried to use this feature I was unable to get it to work since I'm not using any CSS preprocessors.  A project for another time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Responsiveness
&lt;/h4&gt;

&lt;p&gt;Unsurprisingly, Tailwind components support responsive design.  But the thing is, since everything is applied to each component, Tailwind makes it insanely easy to keep your site &lt;em&gt;consistently&lt;/em&gt; responsive.  It has built-in breakpoint prefixes, so you can tell each component what to do when the screen is small, and then how to change when it gets to a medium size, for example.  Personally, breakpoints are one of my biggest pet-peeves about writing CSS because it tends to feel like I'm re-writing the entire style for each breakpoint.  I also get really ADHD about it and end up with two dozen breakpoints, each changing a few things at a time.  Time consuming, inefficient, and unwieldy.  The fact that Tailwind saves me from myself in this regard might make this my favorite feature!&lt;/p&gt;

&lt;h4&gt;
  
  
  Transformations &amp;amp; Transitions
&lt;/h4&gt;

&lt;p&gt;Tailwind even includes transformations and transitions!  For my simple test I didn't use these, but based on how easy all the other utilities have been to use, I'm excited to try these out soon to make the experience of writing transitions better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Not To Like
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Learning Curve
&lt;/h4&gt;

&lt;p&gt;There is a ton of functionality in Tailwind.  This makes it extremely powerful, but it also makes it feel like I have to re-learn CSS.  As I use it more and more, it will undoubtedly become second nature and this won't be an issue anymore, but it certainly takes some getting used to at first.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code Duplication
&lt;/h4&gt;

&lt;p&gt;As I mentioned before, a big drawback of Tailwind is that there is a &lt;strong&gt;LOT&lt;/strong&gt; of duplicated code. In fact, even in my simple testing layout, I would need to manually copy/paste the entire HTML code from the first article to each of the following ones, and let's not even get into what a nightmare it would end up being if you are building HTML elements programmatically in JavaScript!  For example, take a look at all the code I'd need to copy for each and every similar button that I want to put on my page:&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;button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luckily, if you're using a pre-processor, the brilliant creators have already thought of this and they have us covered by including extraction and abstraction features as mentioned in the To-Like section.  It requires another step, but that's a small price to pay for all of the benefits above.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Dreaded Paywall
&lt;/h4&gt;

&lt;p&gt;While there are some very generous free components available, you'll need to fork out some cash in order to get all of them.  Some of these paywalled components (buttons for example) are on the more basic side too.  The good news, of course, is that you can build anything you want using their utilities which are all free, it just takes time and practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;Tailwind is absolutely amazing!  I almost feel like, if I could start all over, it might have been great to learn Tailwind first and THEN learn custom CSS.  It's powerful and customizable enough to perfectly create any style or element that you could ever want, but at the same time it's surprisingly simple to use thanks to the very deliberate and tactical design, and the accompanying documentation.  Definitely beats writing your own CSS, especially if you use a preprocessor and can abstract out some of those common, Tailwind-heavy elements.&lt;/p&gt;

&lt;p&gt;As always, here's my testing layout:&lt;br&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%2Fi%2Fnhffc42zn5543kk18g2h.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%2Fi%2Fnhffc42zn5543kk18g2h.png" alt="Site Layout Using Tailwind"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the code to make it:&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;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt; &amp;lt;/title&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt; 
    &amp;lt;link rel="stylesheet" href="tailwind.css"&amp;gt;  
    &amp;lt;link rel="stylesheet" href="style-tailwind.css"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div class="bg-gray-100 text-gray-500 p-5"&amp;gt;

      &amp;lt;article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5"&amp;gt;
        &amp;lt;figure class="mx-auto pb-4"&amp;gt; 
            &amp;lt;h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center"&amp;gt;Project 1&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://placekitten.com/g/600/300" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="text-center text-sm"&amp;gt;This is the first project in the list.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;span class="mx-auto"&amp;gt;
            &amp;lt;button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Good News!&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
        &amp;lt;/span&amp;gt;
      &amp;lt;/article&amp;gt;

      &amp;lt;article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5"&amp;gt;
        &amp;lt;figure class="mx-auto pb-4"&amp;gt;  
            &amp;lt;h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center"&amp;gt;Project 2&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://mrmrs.github.io/photos/whale.jpg" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="text-center text-sm"&amp;gt;This is Number 2.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;span class="mx-auto"&amp;gt;
            &amp;lt;button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Good News!&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
        &amp;lt;/span&amp;gt;
      &amp;lt;/article&amp;gt;

      &amp;lt;article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5"&amp;gt;
        &amp;lt;figure class="mx-auto pb-4"&amp;gt; 
            &amp;lt;h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center"&amp;gt;Project 3&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://mrmrs.github.io/photos/cpu.jpg" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="text-center text-sm"&amp;gt;Third entry is the charm.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="text-left pb-3 text-lg"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;span class="mx-auto"&amp;gt;
            &amp;lt;button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Good News!&amp;lt;/button&amp;gt;
            &amp;lt;button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
        &amp;lt;/span&amp;gt;
      &amp;lt;/article&amp;gt;

    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, no custom CSS required!&lt;/p&gt;

</description>
      <category>css</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Exploring CSS: Micro-Frameworks (Plume)</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 30 Jan 2021 01:08:25 +0000</pubDate>
      <link>https://dev.to/dhintz89/exploring-css-micro-frameworks-plume-3di8</link>
      <guid>https://dev.to/dhintz89/exploring-css-micro-frameworks-plume-3di8</guid>
      <description>&lt;p&gt;By now, I've spent a LOT of time learning how to effectively use CSS from scratch and I think it's finally time that I stop doing that and allow myself to make my life easier.  To do that, I will be doing an "Exploring CSS" Series where I take a look at libraries, pre-processors, frameworks, and the like to find out which I like and can start using going forward.  &lt;/p&gt;

&lt;p&gt;This is my first entry in the series, and I'll be looking at a micro-framework called &lt;a href="https://felippe-regazio.github.io/plume-css/" rel="noopener noreferrer"&gt;Plume&lt;/a&gt;. Plume is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A lightweight and highly themeable CSS Micro-Framework. Plume is meant to be the lowest CSS layer on your app. [Plume is great for] working on a small to medium application, if you feel that you don't need all the larger frameworks' features, or if you just want to code and grow all the style by yourself. Plume offers a solid, highly customizable and extendable start point. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds like a great starting point to me!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's To Like
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Set Up
&lt;/h4&gt;

&lt;p&gt;First of all, Plume is extremely simple and quite quick to get up and running.  Just download the library (or install it), add the link to your HTML, and add &lt;code&gt;class=”plume”&lt;/code&gt; to the body tag and you’re ready to go.  You could also have certain "plumed" containers if you would like since it's scoped in your HTML, hence needing the &lt;code&gt;class="plume"&lt;/code&gt; line.  In that case, you would just include that in your wrapper element rather than the body tag.&lt;/p&gt;

&lt;h4&gt;
  
  
  Customization
&lt;/h4&gt;

&lt;p&gt;Next up is customization.  My biggest problem with things like Bootstrap is that it creates a sort of cookie-cutter website where nothing really stands out all that much.  Plume; however, is all about creating a custom theme, and it's really easy to do (you barely even need to know CSS).  Everything you need is on the &lt;a href=""&gt;Plume webpage&lt;/a&gt;, that's right - a single page.  You just go through a list of supported attributes and customize each one however you like.  You can see what it will look like on the page itself as you play with each option.  Once you have your theme put together, just click the &amp;lt;/&amp;gt; button and copy/paste the content into the top of your CSS file since it’s just a series of CSS variables.  Want to make a change later on?  Just go to your CSS and change the value for the appropriate variable and watch your whole site change to reflect it!&lt;/p&gt;

&lt;p&gt;Another benefit of this variable approach?  Since it’s so quick and easy to set up a custom theme, you can have a whole bunch of different themes on your site!  Maybe you want different types of containers to have different coloring and font, or maybe you want your user to be able to choose between different theming options.  It's easy to do, you just need a simple JavaScript script to change the relevant variables in your CSS &lt;code&gt;:root&lt;/code&gt; and you're good to go.  In fact, Plume has its own theme picker on the site to demonstrate this concept.  I think adding that element of personal customization is pretty cool, and using Plume, it’s no sweat.&lt;/p&gt;

&lt;h4&gt;
  
  
  Components
&lt;/h4&gt;

&lt;p&gt;Then there's actually building your site.  Plume proved to be excellent for quickly building out basic site structure and linking it all to a home-made, consistent theme.  It comes with some basic styled components, like various types of form inputs and buttons that will automatically sync up with your custom theme thanks to everything linking back to those CSS variables.  It also sets up your basic container styling (sizing, alignment, spacing, etc.) for you, so no more wrestling to get your content centered.&lt;/p&gt;

&lt;p&gt;All of the components are added purely by adding a class to your HTML elements.  There is nothing else that you need to do.  So say you want an element with everything centered &lt;em&gt;except&lt;/em&gt; for the paragraph text.  All you need to do is write some HTML:&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 class="pm-container pm-ground pm-text-center"&amp;gt;
  &amp;lt;h2&amp;gt;Example&amp;lt;/h2&amp;gt;
  &amp;lt;p class="pm-text-left"&amp;gt;Some Text&amp;lt;/p&amp;gt;
  &amp;lt;p class="pm-text-left"&amp;gt;Some Text&amp;lt;/p&amp;gt;
  &amp;lt;button class="pm-btn-success"&amp;gt;Push Me!&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you'll get this:&lt;br&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%2Fi%2F1tk3t9h9blnyg3i25xss.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%2Fi%2F1tk3t9h9blnyg3i25xss.png" alt="Mostly Centered Div"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Responsive
&lt;/h4&gt;

&lt;p&gt;And finally, Plume components are responsive out of the box, which is a huge win.  It doesn't do a whole lot to help you with your site structure (grids, flexbox, layout templates, etc.), but that's not what these micro-frameworks are for, at least in my mind.  You own setting up your site's structure, then you can sit back and let Plume make it look good!&lt;/p&gt;
&lt;h2&gt;
  
  
  What's Not To Like
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Limitations
&lt;/h4&gt;

&lt;p&gt;The options are pretty limited; however, with only about a dozen component families included.  Using only Plume, I was able to get my site’s basic layout looking pretty darn good within an hour, but there is still a lot of individual element customization that I would likely want to add in from this point.  This is, of course, by design.  Remember the creator states "Plume offers a solid, highly customizable and extendable &lt;strong&gt;start point&lt;/strong&gt;."  So just know that you are still going to need to do some custom CSS work after you've "plumed up" your site.&lt;/p&gt;
&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;As this is the first one I'm evaluating, it's hard to say at this time.  But just going on Plume's own merits and not comparing to anything else, I love it!  I would absolutely use this as my starting point when I'm staring at a blank page.  This framework takes a HUGE chunk of the tedious stuff off my plate and makes for a great consistent template for my site to be built upon.&lt;/p&gt;

&lt;p&gt;Here's my simple testing layout using nothing but Plume:&lt;br&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%2Fi%2Fu241ccnprb4tpqurht3a.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%2Fi%2Fu241ccnprb4tpqurht3a.png" alt="Site Layout Using Plume"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And of course, here's the code:&lt;br&gt;
&lt;/p&gt;

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

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt; &amp;lt;/title&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;   
    &amp;lt;link rel="stylesheet" href="plume-css/lib/plume-all.css"&amp;gt;   &amp;lt;!-- Add Plume as a Stylesheet --&amp;gt;
    &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body class="plume"&amp;gt;  &amp;lt;!-- Apply Plume to full site --&amp;gt;
    &amp;lt;div class="pm-container pm-surface"&amp;gt;

      &amp;lt;article class="pm-text-center pm-container pm-ground"&amp;gt;
        &amp;lt;figure class="pm-text-center"&amp;gt; 
            &amp;lt;h3 class="pm-font-secondary"&amp;gt;Project 1&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://placekitten.com/g/600/300" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="pm-font-primary"&amp;gt;This is the first project in the list.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;button class="pm-btn-gradient"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-success"&amp;gt;Good News!&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-error"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
      &amp;lt;/article&amp;gt;

      &amp;lt;article class="pm-text-center pm-container pm-ground"&amp;gt;
        &amp;lt;figure class="pm-text-center"&amp;gt; 
            &amp;lt;h3 class="pm-font-secondary"&amp;gt;Project 2&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://mrmrs.github.io/photos/whale.jpg" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="pm-font-primary"&amp;gt;This is Number 2.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;button class="pm-btn-gradient"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-success"&amp;gt;Good News!&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-error"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
      &amp;lt;/article&amp;gt;

      &amp;lt;article class="pm-text-center pm-container pm-ground"&amp;gt;
        &amp;lt;figure class="pm-text-center"&amp;gt; 
            &amp;lt;h3 class="pm-font-secondary"&amp;gt;Project 3&amp;lt;/h3&amp;gt;
            &amp;lt;img src="http://mrmrs.github.io/photos/cpu.jpg" alt="Visual Store"/&amp;gt;
            &amp;lt;figcaption&amp;gt;
                &amp;lt;p class="pm-font-primary"&amp;gt;Third entry is the charm.&amp;lt;/p&amp;gt;
            &amp;lt;/figcaption&amp;gt;
        &amp;lt;/figure&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Main Features:&amp;lt;/strong&amp;gt; Some cool things are in this.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Backend Techs:&amp;lt;/strong&amp;gt; Here's what I used to build the API.&amp;lt;/p&amp;gt;
        &amp;lt;p class="pm-font-primary pm-text-left"&amp;gt;&amp;lt;strong&amp;gt;Frontend Techs:&amp;lt;/strong&amp;gt; Here's how the site was built.  Make sure to include Plume!&amp;lt;/p&amp;gt;
        &amp;lt;button class="pm-btn-gradient"&amp;gt;Cool Button&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-success"&amp;gt;Good News!&amp;lt;/button&amp;gt;
        &amp;lt;button class="pm-btn-error"&amp;gt;Bad News!&amp;lt;/button&amp;gt;
      &amp;lt;/article&amp;gt;

    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

:root {   /* downloaded from Plume Site */
  --pm-primary-color: #309AFD;
  --pm-secondary-color: #00004b;
  --pm-app-surface-color: #F1F2F3;
  --pm-app-ground-color: #fff;
  --pm-mark-border-radius: 0px;
  --pm-button-border-radius: 0px;
  --pm-input-border-radius: 0px;
  --pm-input-border-width: 1px;
  --pm-pre-code-border-radius: 0px;
  --pm-app-text-color: #848586;
  --pm-app-base-font-size: 19px;
  --pm-app-line-height: 1.2rem;
  --pm-app-container-padding: 1rem 2rem;
  --pm-app-container-max-width: 900px;
}

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

body {
  margin: 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>css</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Convert Your Old Class Components to Functions. Just Do It Already!</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 23 Jan 2021 02:41:51 +0000</pubDate>
      <link>https://dev.to/dhintz89/convert-your-old-class-components-to-functions-just-do-it-already-44e1</link>
      <guid>https://dev.to/dhintz89/convert-your-old-class-components-to-functions-just-do-it-already-44e1</guid>
      <description>&lt;p&gt;It's now generally acknowledged that using hooks in React is better than using classes.  There are a ton of blogs and discussions on the subject and over time they have inched more and more uniformly toward hooks.  Yet my React training still used classes, and I know that many developers still use classes today as well.  My guess is a lot of them do so for the same reason I've been sticking to classes: I'm already familiar with class-based stateful components, and I'd have to re-learn how to implement state and lifecycles if I make the switch.  Maybe that's not the greatest reason, but with so much out there that needs to be learned, it is hard to prioritize learning a new way of doing something when the "old way" is already working perfectly for me today.&lt;/p&gt;

&lt;p&gt;But here's the thing - in React interviews, they expect you to use hooks.  If you use a class you get the toughest interview question of them all..."Why did you do it that way?" 😨...😰...😢&lt;/p&gt;

&lt;p&gt;Luckily, after a &lt;em&gt;ahem&lt;/em&gt; learning experience finally convinced me it's time to learn about hooks, I found out they're really not bad at all, at least in the simplest implementations.  &lt;/p&gt;

&lt;p&gt;There are two "main" hooks and that was all I am initially concerned with: &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt;.  So below, I'm going to create an unstyled digital clock component, using both classes and hooks, to show off how to use both of these.  At the end I'll do a side-by-side comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class
&lt;/h3&gt;

&lt;p&gt;Before we can even get started, we need to set up the component.  first, import React, and its Component class, and then create our Clock component that inherits from it.&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, {Component} from 'react';

export default class Clock extends Component {};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's start by setting up our state.  We need to create a Date Object representing the current date/time and set it in the component's state with a key of &lt;code&gt;currentTime&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;  state = {
    currentTime: new Date
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we can call our render function to display that value in the DOM.  To convert it to a time string, we'll use &lt;code&gt;toLocaleTimeString()&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;import React, {Component} from 'react';

export default class Clock extends Component {
  state = {
    currentTime: new Date
  };

  render() {
    return(
      &amp;lt;h2&amp;gt;{this.state.currentTime.toLocaleTimeString()}&amp;lt;/h2&amp;gt;
    );
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that will display the time on the page.  But to make it a clock, we need it to "tick" each second as time goes by.  We start by defining a &lt;code&gt;tick()&lt;/code&gt; function that sets the state to the new moment in time.  Then we want to call that tick function every second by setting up a one second interval.  For the interval, we need to wait until the component is mounted, then start the interval timer.  To do something "once the component is mounted" we use the &lt;code&gt;componentDidMount&lt;/code&gt; lifecycle method.  Finally, if and when the Clock component is unmounted, we'd want the interval to stop so that the computer isn't constantly counting for no reason.  To do something "once the component is unmounted" we use &lt;code&gt;componentWillUnmount&lt;/code&gt; which runs just before the component is destroyed.&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, {Component} from 'react';

export default class Clock extends Component {
  state = {
    currentTime: new Date
  };

  tick() {
    this.setState({currentTime: new Date});
  };

  componentDidMount() {
    this.int = setInterval(() =&amp;gt; this.tick(), 1000);
  };

  componentWillUnmount() {
    clearInterval(this.int);
  };

  render() {
    return(
      &amp;lt;h2&amp;gt;{this.state.currentTime.toLocaleTimeString()}&amp;lt;/h2&amp;gt;
    );
  };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we have ourselves a ticking clock!&lt;/p&gt;

&lt;h3&gt;
  
  
  Hooks
&lt;/h3&gt;

&lt;p&gt;Now, let's see how to do the exact same thing using hooks.  Again, we need to start by setting up the component.  Notice we need to move the export statement to the bottom now.&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, {useState, useEffect} from 'react';

const Clock = () =&amp;gt; {};

export default Clock;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, once again, we'll set up our state with the same key &amp;amp; value.  Here, we're defining two separate variables at the same time.  &lt;code&gt;currentTime&lt;/code&gt; is our key, and &lt;code&gt;setCurrentTime&lt;/code&gt; equates to calling &lt;code&gt;this.setState()&lt;/code&gt; in a class.  Finally, calling &lt;code&gt;useState&lt;/code&gt; actually calls &lt;code&gt;setCurrentTime&lt;/code&gt;, so you need to pass an argument to set up the initial state, in this case a Date object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [currentTime, setCurrentTime] = useState(new Date);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we render will remain unchanged, but since we're using a functional, not class, component we just need to return the JSX, we don't need to use the &lt;code&gt;render()&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;import React, {useState, useEffect} from 'react';

const Clock = () =&amp;gt; {
  const [currentTime, setCurrentTime] = useState(new Date);

  return(
    &amp;lt;h2&amp;gt;{this.state.currentTime.toLocaleTimeString()}&amp;lt;/h2&amp;gt;
  );
};

export default Clock;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now it's time to get that clock a-ticking.  We'll start by defining that &lt;code&gt;tick()&lt;/code&gt; function again which sets the state to the new moment.  We do this by defining a normal function (&lt;em&gt;there's no class for instance methods&lt;/em&gt;) which uses our new &lt;code&gt;setCurrentTime&lt;/code&gt; function variable to change state.  Where things get interesting is, since there's no lifecycle methods without the class, we need to use &lt;code&gt;useEffect()&lt;/code&gt;.  This function actually includes both the &lt;code&gt;componentDidMount&lt;/code&gt; and &lt;code&gt;componentWillUnmount&lt;/code&gt; methods all in one.  We still need to define our interval and set the callback to &lt;code&gt;tick()&lt;/code&gt;, but now we will have our &lt;code&gt;useEffect&lt;/code&gt; function return &lt;em&gt;another function&lt;/em&gt;. This returned function stands in for &lt;code&gt;componentWillUnmount&lt;/code&gt; and should be used to clean up any services that were started once the component is destroyed.&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, {useState, useEffect} from 'react';

const Clock = () =&amp;gt; {
  const [currentTime, setCurrentTime] = useState(new Date);

  function tick() {
    setCurrentTime(new Date);
  };

  useEffect(() =&amp;gt; {
    let int = setInterval(() =&amp;gt; tick(), 1000);
    return cleanup =&amp;gt; {
      clearInterval(int);
    };
  });

  return(
    &amp;lt;h2&amp;gt;{currentTime.toLocaleTimeString()}&amp;lt;/h2&amp;gt;
  );
};

export default Clock;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we can take this one step further by converting our functions to arrow functions.  Take a look at the side-by-side below to see the refactored component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hooks&lt;/th&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zDWqdv0k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0dhbnxx1q5cvlit8j30u.png" alt="Function-Based Clock Component"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mVv5eGtH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hn720p5u72q2zad3e1n3.png" alt="Class-Based Clock Component"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The functional way looks a lot more concise doesn't it?  So what do you think...are you convinced to start using hooks yet, or do you need to learn the hard way like I did?&lt;/p&gt;

&lt;h4&gt;
  
  
  Since I like to have defined rules so that I can just follow down the list, here is your Converting Class To Function Checklist:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Change the import statement

&lt;ul&gt;
&lt;li&gt;From: &lt;code&gt;import React, {Component} from 'react'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To: &lt;code&gt;import React, {useState, useEffect} from 'react'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Change the component declaration

&lt;ul&gt;
&lt;li&gt;From: &lt;code&gt;export default class Clock extends Component {}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To: &lt;code&gt;const Clock = () =&amp;gt; {&lt;/code&gt; &amp;amp; move the export to the end of the file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Change the state definition

&lt;ul&gt;
&lt;li&gt;From: &lt;code&gt;state = {currentTime: new Date};&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To: &lt;code&gt;const [currentTime, setCurrentTime] = useState(new Date);&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Drop &lt;code&gt;this.state.&lt;/code&gt; from anywhere that uses state data&lt;/li&gt;
&lt;li&gt;Change any &lt;code&gt;this.setState()&lt;/code&gt; to the new function defined in &lt;code&gt;useState&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Change any instance methods/variables to regular functions/variables

&lt;ul&gt;
&lt;li&gt;From: &lt;code&gt;tick() {}&lt;/code&gt; / &lt;code&gt;this.int =&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To: &lt;code&gt;function tick() {};&lt;/code&gt; / &lt;code&gt;int =&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Alt: convert function to arrow function &lt;code&gt;tick = () =&amp;gt; {}&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Finally, change any lifecycle methods to &lt;code&gt;useEffect()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;From: &lt;code&gt;componentDidMount() {};&lt;/code&gt; / &lt;code&gt;componentWillUnmount() {}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To: &lt;code&gt;useEffect()&lt;/code&gt; which returns a cleanup function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Email and Text from Rails</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Thu, 14 Jan 2021 22:40:40 +0000</pubDate>
      <link>https://dev.to/dhintz89/email-and-text-from-rails-5gao</link>
      <guid>https://dev.to/dhintz89/email-and-text-from-rails-5gao</guid>
      <description>&lt;p&gt;Hey Everyone!  &lt;/p&gt;

&lt;p&gt;I've learned, and applied, a lot in the last few months, but there was a big glaring gap that I just hadn't addressed yet, and that was messaging users outside of my own app.  So, to finally get this addressed, I wanted to add functionality to my recipes app to send a shopping list to my users by email and/or text messaging.  &lt;/p&gt;

&lt;p&gt;Email was pretty obvious, there are classes built into Rails called ActionMailers - these allow you to build email templates similar to how you would build a view in a Rails site, and then sends out that email.  Text messaging required a little searching, but ultimately there was a gem that was perfect for my purposes.  Here, I'll go through how to set up the emailing functionality in Rails, and then how that will translate into SMS capability using the &lt;a href="https://github.com/preston/sms-easy"&gt;sms-easy&lt;/a&gt; gem.&lt;/p&gt;

&lt;p&gt;This is broken down into 4 high-level steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuring Rails&lt;/li&gt;
&lt;li&gt;Creating your Mailer&lt;/li&gt;
&lt;li&gt;Setting up your workflow&lt;/li&gt;
&lt;li&gt;Converting the Mailer to use an SMS address&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sending Emails
&lt;/h2&gt;

&lt;p&gt;Like I said above, to send emails from Rails, there is a built in functionality called ActionMailers.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a&gt;Configure Rails Environment&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;The first step for using ActionMailers is to get them configured in our app.  First, we'll add some configuration to each of our environments.  We need to do three things here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tell Rails how we want to deliver our mailer.  In this case, using SMTP: &lt;code&gt;config.action_mailer.delivery_method = :smtp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set up default URL options to say what URL the email will be sent from and how it will be sent&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;host = 'localhost:3000' // this needs to be set to your actual site url in your production environment
config.action_mailer.default_url_options = { :host =&amp;gt; host, protocol: 'http' }
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure the SMTP settings so Rails can log into the correct service, with the proper authorization, and actually send the email.  The below is for Gmail, but there are plenty of other options, such as Outlook, if you don't want to use Gmail just Google "Outlook SMTP Settings":&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  config.action_mailer.smtp_settings = {
    :address              =&amp;gt; "smtp.gmail.com",
    :port                 =&amp;gt; 587,
    :user_name            =&amp;gt; ENV["Email_Username"],
    :password             =&amp;gt; ENV["Email_Password"],
    :authentication       =&amp;gt; "plain",
    :enable_starttls_auto =&amp;gt; true
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Setup the Gmail Account
&lt;/h4&gt;

&lt;p&gt;Notice the lines in the above code that use &lt;code&gt;ENV[]&lt;/code&gt;, these point to an environment variable.  After all, we don't want to have our email login info out there for the whole world to see.  So, the next step is to create these in our .env file (this requires the gem &lt;a href="https://www.rubydoc.info/gems/dotenv-rails/2.7.6"&gt;dotenv-rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, to get the &lt;code&gt;:user_name&lt;/code&gt; and &lt;code&gt;:password&lt;/code&gt;, we'll need to create a Gmail account.  The important thing to keep in mind for this is that, once your account is created, you'll need to go to &lt;code&gt;Settings -&amp;gt; Security -&amp;gt; Signing in to Google&lt;/code&gt; to set up 2-step verification, and then create an App Password to allow your app, a 3rd party app from Google's standpoint, to access your account.  This App Password will be the password you include in the smtp_settings above, not your personal password.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a&gt;Create your Mailer&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;To create the Mailer, you could manually add the files needed, but Rails comes with a handy-dandy generator to do a lot of the setup for us.  Run &lt;code&gt;rails generate mailer shoplist_mailer&lt;/code&gt; and Rails will create a mailer file &lt;code&gt;app/mailers/shoplist_mailer.rb&lt;/code&gt; and a views folder &lt;code&gt;app/views/shoplist_mailer&lt;/code&gt;, along with some testing files.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Mailer
&lt;/h4&gt;

&lt;p&gt;First, make sure that &lt;code&gt;application_mailer.rb&lt;/code&gt; has the correct defaults set up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationMailer &amp;lt; ActionMailer::Base
  default from: "noreply.whats.cookin@gmail.com"
  layout 'mailer'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, within &lt;code&gt;app/mailers/shoplist_mailer.rb&lt;/code&gt; we will add a method to create an email.  This method will receive the arguments from your controller as params, and it needs to convert them to instance variables to be passed into a view. It will then use ApplicationMailer's built in &lt;code&gt;#mail&lt;/code&gt; method to pull the view (which we'll set up in the next step) as the template and pass in those instance variables. It should end up looking 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 ShoplistMailer &amp;lt; ApplicationMailer 
  def new_list_email
    @recipe_name = params[:recipe]
    @user = params[:user]
    @shoplist = params[:shoplist]
    mail(to: @user.email, subject: "What's Cookin' Shopping List")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The View
&lt;/h4&gt;

&lt;p&gt;Now that our Mailer is set up to find a view and pass it information, we need to actually create the view.  We're going to create 2 files under &lt;code&gt;app/views/shoplist_mailer&lt;/code&gt;, the file names need to match the method name in your Mailer (in this case &lt;code&gt;new_list_email&lt;/code&gt;), and they will be nearly identical except that one will be an html file and the other a text file.  What we're doing here is setting up our primary (html) view, and a backup (text) view in case there's an issue with sending html.  You shouldn't need to worry about any of the html setup as it should already be done for you in &lt;code&gt;app/views/layouts/mailer.html.erb&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;This is your email template, so make it your own way, but here is mine as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/views/shoplist_mailer/new_list_email.html.erb

&amp;lt;h3&amp;gt;Hello &amp;lt;%= @user.name %&amp;gt;,&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;
  Here is your shopping list for &amp;lt;strong&amp;gt;&amp;lt;%= @recipe_name %&amp;gt;&amp;lt;/strong&amp;gt;:
&amp;lt;/p&amp;gt;
&amp;lt;ul&amp;gt;&amp;lt;% @shoplist.each do |item| %&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;%= item %&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;% end %&amp;gt;&amp;lt;/ul&amp;gt;

&amp;lt;p&amp;gt;Thank you for using &amp;lt;strong&amp;gt;What's Cookin'&amp;lt;/strong&amp;gt;. Enjoy your meal!&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/views/shoplist_mailer/new_list_email.text.erb

Hello &amp;lt;%= @user.name %&amp;gt;,

Here is your shopping list for &amp;lt;%= @recipe_name %&amp;gt;:

&amp;lt;% @shoplist.each do |item| %&amp;gt;
  &amp;lt;%= item %&amp;gt;
&amp;lt;% end %&amp;gt;

Thank you for using What's Cookin'. Enjoy your meal!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, on to the next piece.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a&gt;Setup Workflow&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Okay, now that we have the email settings configured and our mailers created, all that's left to do is get your workflow set up.  How does it go from a user clicking a button on the page, to sending that email out? &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Note that your use case may not be exactly the same as mine, so the steps may be a little different.  I've tried to note some areas to watch for this, but it's up to you to figure out your app's specific workflow.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a new Route
&lt;em&gt;(this step may not be necessary - for example, if you just need an auto-notification upon user signup it would NOT require a new route)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resources :recipes  // for the basic Recipe model
post '/recipes/send_shoplist' =&amp;gt; 'recipes#send_shoplist'  // specific route for sending a shopping list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add a new Action to Controller
&lt;em&gt;(this step may not be necessary - similar to the route, an auto-notification wouldn't require its own controller action)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/controllers/recipes_controller.rb

def send_shoplist
  // controller code goes here
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Instantiate the Mailer from your Controller and pass in args - this is the step that actually tells Rails to send the email
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// create args from params coming from fetch call
@shoplist = params[:shoplist]
@recipe = params[:recipe]

// pass args to Mailer and call delivery method
ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user).new_list_email.deliver_now
render json: "Shopping List Successfully Delivered".to_json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Connect frontend:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;this entire step may not be necessary - if the user doesn't need to explicitly instruct the app to send them data (ex. auto-notification) there wouldn't necessarily need to be a dedicated call to your API - hence not needing a route and controller action&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here, we need to create a function containing a POST request to the correct Controller action and we'll include whatever data we need for the email in the body (in this case, which recipe and what ingredients were chosen by user). It's also important to keep in mind that the backend will need to know which user to send the email to.  In my case, I could identify the &lt;code&gt;current_user&lt;/code&gt; via my authorization flow, but you may need to pass a &lt;code&gt;user_id&lt;/code&gt; as a param instead.  Once the function is created, we'll attach it as an eventListener somewhere on our page if it's designed as a manual user action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// code doesn't include assigning recipe and list variables
function sendShopList() {
    fetch(`${RECIPES_URL}/send_shoplist`, {
        method: 'POST',
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": // dependent on auth strategy
        },
        mode: 'cors',
        credentials: "include",
        body: JSON.stringify({recipe: recipe, shoplist: list})
    })
    .then(resp =&amp;gt; resp.json())
    .then(msg =&amp;gt; alert(msg))
    .catch(function(error) {
        alert("Shopping List Could Not Be Delivered - Error Unknown")
        console.log(error)
    })
}

// Attach function to a button's eventListener
shopListButton.addEventListener("click", () =&amp;gt; {sendShopList()})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;a&gt;Sending Text Messages (SMS)&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Now that we have our ActionMailers set up, let's add texting functionality as well.  We want our users to be able to choose whether the notification is sent to their email, phone, or both. The good news is that adding the texting functionality is almost effortless.  &lt;em&gt;Note that setting up fields to gather the needed data is outside the scope of this article, but is very important.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How It Works
&lt;/h4&gt;

&lt;p&gt;First thing's first, let's talk about how this actually works.  Like everything else in coding, there are multiple ways to go about texting users.  If you are building a commercial app, you may want to look at a service like Twilio to simplify things and make it fool-proof.  For our app, we're not concerned about being completely sure that 100% of users have a texting option, so we're going to implement a free method of texting instead.  &lt;/p&gt;

&lt;p&gt;As a reminder, the gem we're going to use for this is called &lt;code&gt;sms-easy&lt;/code&gt; so make sure that it's installed in your Gemfile.  This gem takes advantage of mobile carriers' email-to-text services.  Basically, if you send an email to the correct address, it will route to the user as an SMS message instead.  So the &lt;code&gt;sms-easy&lt;/code&gt; gem essentially tracks these special addresses and performs a lookup and transformation based on the phone number and carrier.  As an aside, it also has functionality to directly send the message from the controller, but we don't want to use that, because we want the text to match the email template that our ActionMailers are already sending out.&lt;/p&gt;

&lt;p&gt;So, we need to do 2 things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the special email-to-text address.&lt;/li&gt;
&lt;li&gt;Route our ActionMailer email to that special address.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's look at how it's done.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation
&lt;/h4&gt;

&lt;p&gt;First, we need to update our Mailer from before so that it's flexible enough to change the "to:" address based on passed in input.  All we need to do is modify one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// FROM
mail(to: @user.email, subject: "What's Cookin' Shopping List")

//TO
mail(to: params[:recipient], subject: "What's Cookin' Shopping List")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that's set, we can change the Mailer call in our Controller so that it provides that "to:" value 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;// FROM
ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user).new_list_email.deliver_now

// TO
ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: current_user.email).new_list_email.deliver_now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to add a control flow to our Controller based on the user's contact preference so that the proper "to:" parameter gets passed.  You can certainly to an if...else statement for this, but this is a great use case for a case statement 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;case current_user.contactPreference
when 'email'
  // Code to send Mailer via email
when 'text'
  // Code to send Mailer via text
when 'both'
  // Code to send Mailer via email
  // Code to send Mailer via text
else
  // Can't send option
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, let's fill in that code.  For the email case, we already have the code completed in the previous step, so let's throw it in and add a response message so our app knows everything worked out okay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;when 'email'
  ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: current_user.email).new_list_email.deliver_now
  render json: "Shopping List Successfully Delivered".to_json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the text case, we need to determine what that special carrier address is and pass that address as the recipient parameter instead of the email.  This is where we'll make use of our &lt;code&gt;sms-easy&lt;/code&gt; gem's &lt;code&gt;sms_address&lt;/code&gt; method.  The method returns our special address, so let's assign to a variable (&lt;code&gt;recipient&lt;/code&gt;) and then pass that into our Mailer call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;when 'text'
  recipient = SMSEasy::Client.sms_address(current_user.phone, current_user.carrier)
  ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: recipient).new_list_email.deliver_now
  render json: "Shopping List Successfully Delivered".to_json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the both case, we'll assign the recipient variable the same way, and then we'll simply include both of the Mailer calls.  The final case, of course, is when there is no match.  Normally, this is an error, so we could use &lt;code&gt;begin...raise...rescue&lt;/code&gt; but for my implementation, I preferred to simplify by having my Controller send a message to the front-end and then simply do nothing.  All together, the modified #send_shoplist method looks 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;def send_shoplist
  # send selected recipe-ingredients as shoplist
  @shoplist = params[:shoplist]
  @recipe = params[:recipe]

  # send shoplist via chosen contact preference
  case current_user.contactPreference
  when 'email'
    ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: current_user.email).new_list_email.deliver_now
    render json: "Shopping List Successfully Delivered".to_json
  when 'text'
    recipient = SMSEasy::Client.sms_address(current_user.phone, current_user.carrier)
    ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: recipient).new_list_email.deliver_now
    render json: "Shopping List Successfully Delivered".to_json
  when 'both'
    recipient = SMSEasy::Client.sms_address(current_user.phone, current_user.carrier)
    ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: current_user.email).new_list_email.deliver_now
    ShoplistMailer.with(recipe: @recipe, shoplist: @shoplist, user: current_user, recipient: recipient).new_list_email.deliver_now
    render json: "Shopping List Successfully Delivered".to_json
  else
    render json: "Shopping List Could Not Be Sent - No Valid Contact Preference Selected".to_json
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Now our backend is set up so that it will email &lt;em&gt;and/or&lt;/em&gt; text the user, depending on their contact preference selection.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>beginners</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Typewriter Effect</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 09 Jan 2021 03:00:50 +0000</pubDate>
      <link>https://dev.to/dhintz89/typewriter-effect-3jj</link>
      <guid>https://dev.to/dhintz89/typewriter-effect-3jj</guid>
      <description>&lt;p&gt;I've got this idea for my portfolio site where my name gets typed out when the page loads.  It's going to get fancy, but to start out, I just want to just get the typing effect figured out.  Luckily, I found a library called &lt;a href="https://github.com/mattboldt/typed.js"&gt;Typed.js&lt;/a&gt; which is really simple, and looks really great!&lt;/p&gt;

&lt;p&gt;I was just messing around, so for now I'm just using vanilla JavaScript.  So I started by creating a simple html doc and including the CDN script:&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;head&amp;gt;
  &amp;lt;script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;title&amp;gt;Typing Effect&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;
  &amp;lt;h2&amp;gt;
    &amp;lt;span id="typed"&amp;gt;&amp;lt;!-- content will be typed here --&amp;gt;&amp;lt;/span&amp;gt;
  &amp;lt;/h2&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The simplest way to go is to create a script tag and add the strings you'd like to cycle through as an array.&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;script&amp;gt;
  const typed = new Typed('.element', {
    strings: ['This effect is super cool!', "I'm going to use it.", 'All the time!'],
    typeSpeed: 40
  };
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And boom, already up and running!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/PoMXgARJ3ZLYemVQVx/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/PoMXgARJ3ZLYemVQVx/giphy.gif" alt="Simple Typing Effect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But I wanted to get a little bit more complex and customized.  I want my html to determine what should be typed, not my JavaScript.  At first I thought I would use an html data-attribute, but then I saw that I don't even have to do that, I can write it as regular html, including style tags, and then Typed.js can pick it up and use it directly by setting the &lt;code&gt;stringsElement&lt;/code&gt; option.  I also plan on adding more advanced stuff, so I've broken it out onto it's own &lt;code&gt;script.js&lt;/code&gt; file just to get it out of my html.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// html
&amp;lt;h2&amp;gt;
  &amp;lt;div id="typed-strings"&amp;gt;
    &amp;lt;p&amp;gt;This effect is &amp;lt;mark&amp;gt;&amp;lt;em&amp;gt;super&amp;lt;/mark&amp;gt;&amp;lt;/em&amp;gt; cool!&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;I'm going to use it.&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;For pretty much everything&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;span id="typed"&amp;gt;&amp;lt;!-- content will be typed here --&amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;/h2&amp;gt;

// JavaScript
const typed = new Typed('#typed', {
  stringsElement: '#typed-strings',
  typeSpeed: 40
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, playing around with its other features, I landed on these options.  I slowed it down a little, added a delay before the text gets deleted, and changed the cursor to an underscore to simulate a terminal.  To make the terminal effect pop, I also customized the cursor element with CSS.  I also wanted it to repeat 3 times, so I added the &lt;code&gt;loop&lt;/code&gt; and &lt;code&gt;loopCount&lt;/code&gt; options 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;// JS
const typed = new Typed('#typed', {
  stringsElement: '#typed-strings',
  typeSpeed: 40,
  backDelay: 1000,
  loop: true,
  loopCount: 3,
  cursorChar: '_'
});

// css
.typed-cursor {
  font-weight: 900;
  box-shadow: 0px 1px;
  font-size: 1.3em;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there I have it, in just a few minutes of messing around I had a perfect typing effect.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/m3DHoz0TfbU3CeNzOl/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/m3DHoz0TfbU3CeNzOl/giphy.gif" alt="Full Typing Effect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next step will be to get really customized, including placement and variable colors, but that's a project for next week.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>2020 In The Rear-View</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 02 Jan 2021 00:18:28 +0000</pubDate>
      <link>https://dev.to/dhintz89/2020-in-the-rear-view-5h1p</link>
      <guid>https://dev.to/dhintz89/2020-in-the-rear-view-5h1p</guid>
      <description>&lt;p&gt;2020 is finally over, and what a year it's been!  As I was sipping on my year-end champagne last night and contemplating the year, I thought it would be fun to write an article about the past year -  my struggles and victories and what I've learned from them - as well as my future goals for 2021.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Struggles
&lt;/h2&gt;

&lt;p&gt;There were a lot of struggles in 2020.  I was working full time, but getting hired as a developer out of a bootcamp requires a LOT of work, so my biggest struggle right out of the gate was (and still is) time management.  I learned to spend 30-45 minutes at the beginning of each day sipping on my coffee and literally breaking the day into chunks.  For each chunk, I block off time in my calendar and set an alert for when it's time to pivot.  Game-changer.&lt;/p&gt;

&lt;p&gt;Related to this is just the sheer amount of work that I have on my plate!  I have projects that are half-done, many more that are finished, but need major overhauls now that I've levelled up my knowledge.  There are frameworks and even other languages that I am dying to learn.  It's been tough to prioritize and slowly chip away at the list, but I am getting there, piece by piece.  I've had to adapt the above time-management strategy to a week-by-week schedule in order to set and focus on my weekly priorities to avoid getting lost in the sea of to-do's.&lt;/p&gt;

&lt;p&gt;There is also the major challenge of staying motivated and positive.  There was a lot of rejection this year while job-hunting.  Most companies did not even bother to reject my applications, I just never heard back.  In fact, in my 4 months of job-hunting, I only got 2 interviews, neither of which progressed to a second interview...talk about disappointing!  But on the bright side, through connecting with others in the field, I learned that the software engineering community is unbelievably supportive!  Seriously, not only were people very happy to share their stories, which all involved similar hardships (aka I'm not the only one!), but I had people that I barely knew offer to help push my resume directly to hiring managers, share awesome resources, offer to pair-code, and on and on.  I'm pretty good at staying motivated in the face of failure, but this super-positive community kept me from feeling totally defeated.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Victories
&lt;/h2&gt;

&lt;p&gt;It's actually been difficult to reflect on my victories due to the very top-of-mind lack of success in my job hunt so far, but when I stop and really think about it, I've actually accomplished a &lt;strong&gt;ton&lt;/strong&gt; over the year that I'm very proud of.  Firstly, I graduated from the Flatiron program, which is deserving of celebration in itself.  I've also built and launched my &lt;a href="http://developer-dan.com/"&gt;personal portfolio site&lt;/a&gt; which, though there's plenty that I still need to do with it, is looking pretty damn good!  I also launched one of my projects, a &lt;a href="https://dhintz89.github.io/whats_cookin_frontend/"&gt;recipe finder&lt;/a&gt;, and have been steadily improving it over the course of the year.  It might not be the prettiest site on the internet, but the functionality is pretty cool, and I've found myself using it several times already.&lt;/p&gt;

&lt;p&gt;Upon graduation, I felt like the tiniest little fish in the giant ocean.  I dreaded putting out a blog because "I didn't know anything that anybody would want to read about," but now after 20 weeks, I have almost 250 followers, and nearing 10,000 views!  This community has been super supportive and have shown me that, even though there's an infinite amount that I &lt;em&gt;don't&lt;/em&gt; know, there are actually plenty of things that I &lt;em&gt;do&lt;/em&gt; know which are more interesting that I would have originally given myself credit for.  I really can't say enough how much I appreciate of all of you who have been reading my posts and providing constructive commentary!  I've actually started looking forward to opening up DEV and joining in on conversations whenever I can.&lt;/p&gt;

&lt;p&gt;Finally, I've overcome what I call "technical paralysis."  Flatiron doesn't really teach anything about algorithms, so when I graduated and started engaging in the real-world and preparing for technical interviews, I was horrified to see the types of things that I can expect in the whiteboarding sessions.  When I took my first practice interview, I got so frustrated and overwhelmed by the problem that I completely froze up and entirely forgot the basics of JavaScript while I was on the call...not a good look.  Through countless hours of study and practice though, I am now quite proud of my ability to think more programmatically and solve these algorithmic problems step-by-step.  Though I still have a very, very long way to go, the support from the developer community has helped me become confident in my ability to pass the interviews.  I now feel "good enough," and during my last practice interview I was able to sound intelligible and confident, even in the face of not knowing the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Level-Ups
&lt;/h2&gt;

&lt;p&gt;Obviously, I've already gone over a lot of general learnings from the year, but as I reflected on the year, I realized that I've come a very, very long way in terms of technical knowledge since I graduated.  It's worth documenting all the self-learning that I've accomplished in addition to everything up above.  This is not an exhaustive list, but it hits the highlights.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS Variables and their applications in website theming&lt;/li&gt;
&lt;li&gt;Major improvements in understanding of CSS styling.  A big moment was understanding the relation of a relative positioned element to everything downstream from it.&lt;/li&gt;
&lt;li&gt;While we're on CSS, I've gotten comfortable using Flexbox, CSS Grids, and combining the two&lt;/li&gt;
&lt;li&gt;I've used and customized Bootstrap, and I've decided I prefer to create my own styling whenever possible&lt;/li&gt;
&lt;li&gt;I'm no longer scared of &lt;code&gt;this&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;I've learned how to test code, including in some complex scenarios&lt;/li&gt;
&lt;li&gt;I've learned how to measure the performance of my code&lt;/li&gt;
&lt;li&gt;Authentication is now a breeze - I've even combined Rails' Devise with JWT&lt;/li&gt;
&lt;li&gt;I can build an API without a corresponding front-end thanks to Postman. And thanks to this community, I've also learned about a potentially better solution: Insomnia&lt;/li&gt;
&lt;li&gt;I've used Rails' Action Mailer to send assign custom communications to site events&lt;/li&gt;
&lt;li&gt;I've learned some basics of PHP (more to come on this)&lt;/li&gt;
&lt;li&gt;Through research and experimentation, I've built a complex program in VisualBasic, despite not knowing the language&lt;/li&gt;
&lt;li&gt;I've learned to break down a problem and think about it programmatically to devise algorithms&lt;/li&gt;
&lt;li&gt;I've learned about Big O Notation and can calculate it&lt;/li&gt;
&lt;li&gt;I've really levelled up my Git skills, pull-requests, resetting HEADs, managing multiple branches and remotes, and more&lt;/li&gt;
&lt;li&gt;Basic DevOps stuff - putting a site online, buying and setting up a domain, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wow that's a lot - it's easy to lose perspective, but man I've killed it this year! 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  2021 - The Best Is Yet To Come
&lt;/h2&gt;

&lt;p&gt;2021 is going to be my year! I've come too far to stop now.  But what is on the horizon for me?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My number one goal, of course, is to find employment as a developer.  It's been tough going, but things are starting to look a little brighter.&lt;/li&gt;
&lt;li&gt;I will continue to get more involved in the developer community.  I can't wait until I'm on the other side, giving advice rather than receiving it!&lt;/li&gt;
&lt;li&gt;I will begin contributing to OpenSource in earnest.  Once I've finished checking off my personal priorities, this is top of mind.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;WILL&lt;/strong&gt; learn a new language.  Depending on the requirements of my job, I may need to learn a language for their specific stack. If that's not the case, then I will be self-learning starting with PHP. At the moment, I plan to move on to Java after that.&lt;/li&gt;
&lt;li&gt;I will learn jQuery.  I've already used it a bit, but I'm nowhere near fluent yet.  With this and PHP under my belt, I'll be able to work on the vast majority of the existing content on the internet.&lt;/li&gt;
&lt;li&gt;Lastly, but perhaps most importantly I will enjoy the summertime!  I moved to the beach 3 years ago, but my journey into development has taken all of my free-time ever since.  This year, the worst will be over and I'll finally be able to kick back and relax, at least from time to time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So there it is, 2020 gone, 2021 has finally come.  Happy New Year everyone, I hope you're all as excited as I am.  See you all on the other side!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Lambdas and '&amp;' in Ruby</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Thu, 24 Dec 2020 18:41:58 +0000</pubDate>
      <link>https://dev.to/dhintz89/lambdas-and-in-ruby-72p</link>
      <guid>https://dev.to/dhintz89/lambdas-and-in-ruby-72p</guid>
      <description>&lt;p&gt;&lt;code&gt;places.map(&amp;amp;:city)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I've seen this pattern a lot in Rails and have wondered what exactly it's doing.  In researching it, I learned about lambda functions and procs in Ruby, and that in turn led to last week's post about &lt;a href="https://dev.to/dhintz89/functions-creating-functions-ruby-edition-1j1a"&gt;currying functions in Ruby&lt;/a&gt;, which relies on basic lambda functionality.  Going a bit further, I started looking into the beforementioned pattern, now knowing a bit more about lambdas.  At first, I thought I'd understood it, but then I realized that it was more complicated than it initially seemed.  The part that was most confusing to me was whether or not the lambda call was supposed to be a symbol, so this is a quick guide for when to use a symbol in this pattern and when not to, as well as an explanation of why.&lt;/p&gt;

&lt;h4&gt;
  
  
  Here's the TL;DR version if you're not interested in the investigation and the why:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Symbol&lt;/th&gt;
&lt;th&gt;Don't Use Symbol&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Method &lt;strong&gt;belongs to the object&lt;/strong&gt; you are iterating on&lt;/td&gt;
&lt;td&gt;Using a Lambda you've created&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterating on array of objects and operating on a property&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Okay now let's look at how I got here.
&lt;/h3&gt;

&lt;p&gt;First thing, let's create a lambda function for use throughout this guide.  If you read last week's post, this will look very familiar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;half = -&amp;gt;(numerator) {
    if numerator % 2 === 0
        return numerator / 2
    end
    return "#{numerator} can't be halved evenly"
}

puts half.call(10)
  # =&amp;gt; 5
puts half.call(3)
  # =&amp;gt; "3 can't be halved evenly"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is super common for iterators, so we'll want a couple of arrays too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numarry = [0, 1, 2, 3, 4]
textarry = ["a", "b", "c"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, so what now?&lt;/p&gt;

&lt;p&gt;Say we want to half each of the integers in numarry.  We should be able to use '&amp;amp;:' in an iterator to call our lambda like this, right?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts numarry.map(&amp;amp;:half)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrong! You get &lt;code&gt;undefined method 'half'&lt;/code&gt; error!&lt;/p&gt;

&lt;p&gt;The reason is because &lt;code&gt;half&lt;/code&gt; is a lambda, not a symbol, so you need to change it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts numarry.map(&amp;amp;half)
  # =&amp;gt; [0, "1 can't be halved evenly, 1, "3 can't be halved evenly", 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That makes sense (and seems obvious), so then what's with the symbol pattern at the top?  I can't just convert my method to a symbol, so it's not just a matter of preference. Something else must be going on.&lt;/p&gt;

&lt;p&gt;I tried a different method, but this time I decided to use a built-in method instead of a local one that I created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts textarry.map(&amp;amp;upcase)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I got an &lt;code&gt;undefined local variable or method 'upcase'&lt;/code&gt; error!  So, just for fun, I tried it as a symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts textarry.map(&amp;amp;:upcase)
  # =&amp;gt; ["A", "B", "C"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voila - it worked!  But the question is &lt;em&gt;why&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;We know that everything in Ruby is an object, ultimately inheriting from the global class &lt;code&gt;Object&lt;/code&gt;.  When you define a method, it's defined with an object as its owner.  You can see what the owner of a given method is by using the #owner method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def double(num)
  num * 2
end

puts method(:double).owner
  # =&amp;gt; Object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but what about our lambda method at the top?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts half.class
  # =&amp;gt; Proc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So our lambda is not on the same object as the &lt;code&gt;Integer&lt;/code&gt; that we are calling it on.  This gives me an idea!  If we think back to the original pattern: &lt;code&gt;places.map(&amp;amp;:city)&lt;/code&gt; the symbol is a property of the &lt;code&gt;Place&lt;/code&gt; class, similar to how &lt;code&gt;upcase&lt;/code&gt; is technically a property of the &lt;code&gt;String&lt;/code&gt; class.  Meanwhile, our poor lambda is out there on its own and not associated to anything.  There's the difference!  Time to test the theory.  If I'm correct, then by adding a method to an existing class, I should be able to pass it as a symbol to my iterator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# modify Integer class to include double method
class Integer
  def double
    self * 2
  end
end

puts numarry.map(&amp;amp;:double)
  # =&amp;gt; [0, 2, 4, 6, 8]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked!  After all this investigating, I finally came to the simple guidelines below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Symbol&lt;/th&gt;
&lt;th&gt;Don't Use Symbol&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Method &lt;strong&gt;belongs to the object&lt;/strong&gt; you are iterating on&lt;/td&gt;
&lt;td&gt;Using a Lambda you've created&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterating on array of objects and operating on a property&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As a bonus, I gained a stronger understanding of how Ruby works under the hood, which is always a good thing!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Functions Creating Functions! (Ruby edition)</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 19 Dec 2020 03:44:41 +0000</pubDate>
      <link>https://dev.to/dhintz89/functions-creating-functions-ruby-edition-1j1a</link>
      <guid>https://dev.to/dhintz89/functions-creating-functions-ruby-edition-1j1a</guid>
      <description>&lt;p&gt;A couple weeks ago, I wrote a blog about &lt;a href="https://dev.to/dhintz89/functions-creating-functions-3ap2"&gt;building function-building functions in JavaScript&lt;/a&gt;.  This week, I'm going to go through the same concept using Ruby.  I'm going to stick as closely as possible to the same flow as the last article to make it easy to compare.&lt;/p&gt;

&lt;p&gt;We all know what a programming function is and what it does. It encapsulates a particular behavior. For example, this function divides any number you'd like by 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def divide_by_5(number)
    number / 5
end

divide_by_5(15)
  # =&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In life, we often see different variations of a complex behavior, and this is a situation we see a lot in programming as well. For example, imagine we wanted to add some complexity to the above function so that it only divides numbers that are cleanly divisible by 5. We could easily do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def divide_evenly_by_5(num)
    if num % 5 === 0
        return num / 5
    end
    return "#{num} is not divisible by 5!"
end

divide_evenly_by_5(15)
  # =&amp;gt; 3
divide_evenly_by_5(7)
  # =&amp;gt; "7 is not divisible by 5!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we might need to similarly divide by other numbers later on in our program. We could write a new function for each number, but that would be a pain. Instead, let's create a function which in turn creates other functions!&lt;/p&gt;

&lt;p&gt;To do this, we'll convert our function into something called a &lt;a href="https://www.rubyguides.com/2016/02/ruby-procs-and-lambdas/"&gt;lambda function&lt;/a&gt;, which is basically a way to encapsulate a certain behavior into a variable, very similar to &lt;code&gt;const myFunction = function(arg) { console.log("hi "+ arg) }&lt;/code&gt;.  We need to use &lt;code&gt;.call()&lt;/code&gt; to call this lambda function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;divide_evenly_by_5 = -&amp;gt;(numerator) { 
    if numerator % 5 === 0
        return numerator / 5
    end
    return "#{numerator} is not divisible by 5!"
}

divide_evenly_by_5.call(15)
  # =&amp;gt; 3
divide_evenly_by_5.call(7)
  # =&amp;gt; "7 is not divisible by 5!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is too strict!  Let's loosen up the lamda so that we can use whatever numerator AND denominator that we want.  This is how we set up our flexibility in Ruby, rather than the wrapper function that we used in JavaScript.  It's basically the same thing that we did in the JavaScript tutorial, but in reverse. &lt;em&gt;(Instead of building a super-function out of 2 smaller functions, we're building a super-function and then breaking it into 2 smaller functions.)&lt;/em&gt; Note that the order of your arguments are important here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;divide_by = -&amp;gt;(divisor, numerator) { 
    if numerator % divisor === 0
        return numerator / divisor
    end
    return "#{numerator} is not divisible by #{divisor}!"
}

divide_by.call(5, 15)
  # =&amp;gt; 3
divide_by.call(5, 7)
  # =&amp;gt; "7 is not divisible by 5!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to use a concept called currying to essentially split this method up into 2 "parts." and in Ruby we use a &lt;code&gt;.curry&lt;/code&gt; method to do it.  This is going to represent whatever the first &lt;code&gt;divide_by&lt;/code&gt; argument is, which is why it's important to order them correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;divide_by_5 = divide_by.curry.call(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can call &lt;code&gt;divide_by_5&lt;/code&gt; and provide the second argument, in this case the numerator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;divide_by_5.call(10)
  # =&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit of this pattern is that we can now assign this behavior to any divisor/number variation. As the complexity of the behavior goes up, this becomes more and more useful.&lt;/p&gt;

&lt;p&gt;Here's the full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;divide_by = -&amp;gt;(divisor, numerator) { 
    if numerator % divisor === 0
        numerator / divisor
    end
    return "#{numerator} is not divisible by #{divisor}!"
}

divide_by_5 = divide_by.curry.call(5)
  # =&amp;gt; 
div_by_8 = divide_by.curry.call(8)
  # =&amp;gt; 
divide_number_by_100 = divide_by.curry.call(100)
  # =&amp;gt; 

divide_by_5.call(15)
  # =&amp;gt; 3

divide_by_5.call(8)
  # =&amp;gt; "8 is not divisible by 5!"

divide_number_by_100.call(500)
  # =&amp;gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Disclaimer: There is a LOT more to these lambdas than this application, they're super useful in Ruby coding. I'm just getting started diving into their functionality.&lt;/p&gt;

</description>
      <category>ruby</category>
    </item>
    <item>
      <title>CSS Plate for Your Recipe App</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 12 Dec 2020 03:17:26 +0000</pubDate>
      <link>https://dev.to/dhintz89/css-plate-for-your-recipe-app-29p7</link>
      <guid>https://dev.to/dhintz89/css-plate-for-your-recipe-app-29p7</guid>
      <description>&lt;p&gt;I was short on time this week, so I've decided to do a short and simple post - I'm going to build a plate design using CSS.  I will be using it in my &lt;a href="https://dhintz89.github.io/whats_cookin_frontend/" rel="noopener noreferrer"&gt;recipe website&lt;/a&gt; to house the returned recipes, the idea is that it'll look like each recipe is sitting on a plate.&lt;/p&gt;

&lt;p&gt;Starting out, I want to use the least html as possible so that I don't need to keep track of the extra elements.  I'm going to have a plate div, which will serve as a wrapper and the rim of the plate, and an inner_plate span that will be the center of the plate and will hold the content.&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 class="plate"&amp;gt;
  &amp;lt;span class="inner_plate"&amp;gt;&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next I'll add the CSS to make the design come to life.  There are a few key highlights here to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each recipe will have an image, which is what will dictate the sizing, and I set each image size to 240x150 in the imported html.  Because of this, each plate should be fairly uniform in size and shape (it might elongate a little with a really long recipe title due to wrapping, which is okay for my purposes).
&lt;/li&gt;
&lt;li&gt;By then setting &lt;code&gt;.plate&lt;/code&gt; and &lt;code&gt;.inner_plate&lt;/code&gt; size to &lt;code&gt;fit-content&lt;/code&gt; I can rely on padding and margins to give a flexible shape to each design.&lt;/li&gt;
&lt;li&gt;Setting font-size on the &lt;code&gt;plate&lt;/code&gt; element allows me to use em/rem to provide flexible sizing for the box-shadows (since they can't use percentage values).&lt;/li&gt;
&lt;li&gt;The outer box-shadow provides the shadow effect that makes the plate look 3D, while the inner shadow makes is what makes it look like there's a sloping edge from the rim to the main part of the plate.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.plate {
  position: relative;
  display: inline-flex; // inline so plates can organize next to one another
  flex-direction: column;
  height: fit-content;
  width: fit-content;
  background-color: #e4e4e4;
  border-radius: 50%;
  justify-content: center;
  font-size: 15px;
  box-shadow: 2px 2px 8px 2px #000;
  padding: 30px;
  margin: 20px;
}

.inner_plate {
  align-self: center;
  border-radius: 50%;
  height: fit-content;
  width: fit-content;
  border: #dddddd solid 2px;
  background-color: #d2d2d2;
  font-size: 1rem;
  box-shadow: 0 0 10px 10px #cfcfcf;
  justify-content: center;
  padding: 25px;
  text-align: center;
}

.inner_plate img {
    margin-top: 5px;
    max-width: 100%;
    max-height: 150px;
    border-radius: 40%;
    z-index: 1;
    position: relative;
    margin: 25px 2px;
}

.inner_plate h3 {
    max-width: 250px;
    padding: 0 15px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, I want to add a lighting effect to my plate to go along with the shadow that I gave it.  Since I'm keeping HTML to a minimum, I'll use an &lt;code&gt;::after&lt;/code&gt; pseudo-element to add a glare.  An offset box-shadow will give it that soft glare-like edge and it can scale along with the inner-plate because it's all set relative to the inner-plate sizing (size is percentage of inner_plate size &amp;amp; box-shadow is percentage of font-size).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.inner_plate::after {
  content: "";
  position: absolute;
  background-color: #e3e3e3;
  height: 40%;
  width: 20%;
  display: block;
  border-radius: 50%;
  transform: rotate(34deg);
  right: 21%;
  top: 42%;
  font-size: inherit;
  box-shadow: -.6em .2em 1em 1em #e3e3e3;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there it is!  When empty, you can really see how the subtle lighting effect makes it look more realistic and makes the shadow look real:&lt;br&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%2Fi%2F3thmhdv2eul2qjoqmnnf.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%2Fi%2F3thmhdv2eul2qjoqmnnf.png" alt="Empty Plate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's how it looks once it's filled with a recipe:&lt;br&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%2Fi%2Feld41sweszlhyl65sp1w.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%2Fi%2Feld41sweszlhyl65sp1w.png" alt="Filled Plate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think this little effect makes my site a lot more fun and engaging.  Here what it looks like when you search for recipes on the site.&lt;/p&gt;

&lt;p&gt;Before:&lt;br&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%2Fi%2Fd561ndl9az2zx1pzrho7.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%2Fi%2Fd561ndl9az2zx1pzrho7.png" alt="Whats Cookin Website Cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After:&lt;br&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%2Fi%2Fd6lmcc636la9o41p5mwu.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%2Fi%2Fd6lmcc636la9o41p5mwu.png" alt="Whats Cookin Website Plates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty neat, huh?&lt;/p&gt;

</description>
      <category>css</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Devise and JWT in Rails</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 05 Dec 2020 02:09:03 +0000</pubDate>
      <link>https://dev.to/dhintz89/devise-and-jwt-in-rails-2mlj</link>
      <guid>https://dev.to/dhintz89/devise-and-jwt-in-rails-2mlj</guid>
      <description>&lt;p&gt;I needed to implement Devise and JWT using Rails (Rails 5), and I thought, how hard could this be?  Boy was I naive...  Now there is a lot of information out there on how to do this, but each resource was using a different method and nothing really seemed to work.  Well, I've finally figured it out and I want to share it with the world for 2 reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It may save someone days of researching and trial-and-error.&lt;/li&gt;
&lt;li&gt;Selfishly, I want to know where I can go to look it up for next time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Warning, this post will assume some knowledge of Rails and a few popular gems, it's a little bit more advanced than my normal stuff so far.  So here we go.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;First thing's first, there are a few ways this can be handled.  There is (was?) a Devise-JWT gem that integrated JWT and worked very similarly to Devise's regular flow.  When I tried to go that route, it did not work and I wasted many, many hours troubleshooting.  I did eventually succeed in registration, but the sign_in functionality was still not working.  It's very probable that this was do to user error, but regardless, I found my way to be much simpler.&lt;/p&gt;

&lt;p&gt;Here's how it works.&lt;br&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%2Fi%2Fwsmcg0zovzuqxyexu5fh.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%2Fi%2Fwsmcg0zovzuqxyexu5fh.png" alt="Devise and JWT Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So basically, you can really think about this in two steps.  Step 1 is the standard devise-driven authentication.  Step 2 is passing the JSON Web Token back and forth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Project Generation
&lt;/h4&gt;

&lt;p&gt;First, let's build our project.  Since we don't need the full Rails functionality because we'll be setting up a separate front-end, we can use the --api flag &lt;code&gt;rails new example-project --api&lt;/code&gt;.  One of the effects of this flag is that the project will be set up without rails sessions - this is important.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gemfile
&lt;/h4&gt;

&lt;p&gt;Once we've built our project, first thing we'll do is build out the Gemfile.  For the purposes of our authentication flow, we'll need 3 gems&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;devise&lt;/code&gt; for actual authentication &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jwt&lt;/code&gt; for handling the JSON Web Tokens we'll be passing back and forth.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bcrypt&lt;/code&gt; for password-related unit testing - this only needs to be included in the test environment because otherwise it's included in Devise.&lt;/li&gt;
&lt;li&gt;BONUS: I pretty much always add &lt;code&gt;pry&lt;/code&gt; to help with debugging, and it comes in real handy when I need to check what params are coming over.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Devise Initializer
&lt;/h4&gt;

&lt;p&gt;To configure Devise, we'll run &lt;code&gt;rails generate devise:install&lt;/code&gt; from our console to create an initializer file: config/initializers/devise.rb. The good news is that we can largely keep the default configuration; the only special thing we need to do is to set &lt;code&gt;config.skip_session_storage = [:http_auth]&lt;/code&gt; &lt;em&gt;(about quarter way down the file)&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  User Model
&lt;/h4&gt;

&lt;p&gt;Now we need to set up our user model.  Devise has a special way to do this by running &lt;code&gt;rails generate devise User&lt;/code&gt;. This command creates a User model and prefills it with some Devise functionality, it also creates a database 'devise_create_users' migration, and adds a line to the routes file: &lt;code&gt;devise_for :users&lt;/code&gt; which creates routes to the default Devise Controllers.&lt;/p&gt;

&lt;p&gt;Once the User model is created, we can finish configuring Devise by selecting which modules we want and adding it after the &lt;code&gt;devise&lt;/code&gt; macro.  For my app, I just used the basic defaults: &lt;code&gt;devise :database_authenticatable, :registerable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One last thing before we can call the User model ready.  Since a given JSON Web Token (JWT) will be associated to a given user, it makes sense to think of a user "creating" their token.  Additionally, the goal is to get as much of the app's logic in the models, so to address both of these concerns we will place the logic of creating a JWT in the User model.  Here we use the JWT gem to encode a token containing only the user's id.  How can the id be the only thing we need you ask?  Thinking back to our "How Does It Work" Diagram above, remember that the user will need to pass in their credentials as parameters at the sign-in page and, if successful, the server will issue an encrypted token for them.  This is that token, so it will only be used to authenticate that the user is who they say they are once they've &lt;strong&gt;already logged in&lt;/strong&gt; and they try to make a subsequent call to the API.  Thus, we only need a way to identify the user: their unique &lt;code&gt;id&lt;/code&gt; attribute works perfectly for this purpose.&lt;/p&gt;

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

def generate_jwt
  JWT.encode({id: id, exp: 60.days.from_now.to_i}, Rails.application.secrets.secret_key_base)
end


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Routes
&lt;/h4&gt;

&lt;p&gt;As stated above, the &lt;code&gt;rails generate devise User&lt;/code&gt; generator will create a route for us automatically that looks like this: &lt;code&gt;devise_for :users&lt;/code&gt;.  For our purposes, the default controllers aren't going to work on their own because they are meant to operate via sessions, which we will not have in our api-only implementation.  So, we'll need to overwrite some of the default functionality - to do this, we need to point to custom registrations and sessions controllers:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

devise_for :users,
controllers: {
  registrations: :registrations,
  sessions: :sessions
}


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Database
&lt;/h4&gt;

&lt;p&gt;Also stated above, the &lt;code&gt;rails generate devise User&lt;/code&gt; generator will create our database migration for us, so the only change we need to make is uncommenting any non-default modules you added in your User model, as well as adding any custom fields you may need.  Once you're done, run &lt;code&gt;rake db:migrate&lt;/code&gt; and we're done here.&lt;/p&gt;
&lt;h2&gt;
  
  
  Intermission (Coffee Break)
&lt;/h2&gt;

&lt;p&gt;We've gotten through a lot already, but there's quite a bit more to come, so before we get into the controllers, which contain most of our logic and functionality, take a quick breather and grab a fresh cup of coffee.  If you're following along, this is a good time to double check that everything is correct in your app so far...&lt;/p&gt;

&lt;p&gt;Ready to continue?  Okay, let's do this!&lt;/p&gt;
&lt;h2&gt;
  
  
  Controllers
&lt;/h2&gt;

&lt;p&gt;There are three controllers that we're going to be concerned with for this, and each of these 3 controllers will have a specific job from the diagram at the top of this article.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Application Controller&lt;/strong&gt; is where we will process a JWT when a user sends a request to our API.  It's vital to keep in mind that the Application Controller is not concerned with credentials - it simply checks for a valid JWT.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Registrations Controller&lt;/strong&gt; is where a user will create his/her credentials, and it will assign the JWT to the user once complete.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Sessions Controller&lt;/strong&gt; is where a user will authenticate his/her credentials and it will assign the JWT to the user if successful.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Application Controller &amp;lt; ActionController::API
&lt;/h4&gt;

&lt;p&gt;We will set up our JWT processing functionality first because, once a JWT is assigned, we'll want to check to make sure it's working correctly.  Since we know that we will be passing in JSON, we will start off the Application Controller with the following line &lt;code&gt;respond_to :json&lt;/code&gt;. Since all other controllers inherit from the Application Controller, we only need to do this for this controller - it will automatically be passed down to the rest.  This is also where we'll want to provide our app with similar private methods to what the standard Devise implementation would give us, so let's set up our authentication method &lt;code&gt;authenticate_user!&lt;/code&gt; as well as a &lt;code&gt;signed_in?&lt;/code&gt; and &lt;code&gt;current_user&lt;/code&gt; method, then we'll look at how to get them to work.&lt;/p&gt;

&lt;p&gt;For our &lt;code&gt;authenticate_user!&lt;/code&gt;, we know that we want this to reject a user as unauthorized unless they are correctly signed in.  We also know we'll eventually have a &lt;code&gt;signed_in?&lt;/code&gt; method available, so let's go ahead and proceed using that:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

def authenticate_user!(options = {})
  head :unauthorized unless signed_in?
end


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

&lt;/div&gt;

&lt;p&gt;But for this to work, of course, we need to define &lt;code&gt;signed_in?&lt;/code&gt;.  Default Devise does this by checking the session for the presence of a user_id.  We won't have a session for this, but what we &lt;em&gt;will&lt;/em&gt; have is a JWT.  We now know that we need a method to somehow pull a user's &lt;code&gt;id&lt;/code&gt; out of the JWT and return it.  Let's call it &lt;code&gt;@current_user_id&lt;/code&gt; and use that future value in our signed_in? method like so:&lt;/p&gt;

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

def signed_in?
  @current_user_id.present?
end


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

&lt;/div&gt;

&lt;p&gt;While we're at it, since we know that we'll have a &lt;code&gt;@current_user_id&lt;/code&gt; to work with, let's use it to define our current_user method too.  We need this to take the id and search our database for a corresponding user record:&lt;/p&gt;

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

def current_user
  @current_user ||= super || User.find(@current_user_id)
end


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

&lt;/div&gt;

&lt;p&gt;That's easy enough, essentially just copying the Devise methods, now we just have to find a way to extract that id from a passed JWT.  One final reminder: remember that this controller is &lt;strong&gt;NOT&lt;/strong&gt; meant to make sure that the user authenticates against his/her credentials, it's just to see whether they are signed in or not by looking at the JWT.  If a user &lt;em&gt;HAS&lt;/em&gt; a valid JWT, it means that they have correctly authenticated their credentials and the server &lt;em&gt;gave&lt;/em&gt; them one.  With that in mind, this is actually super simple using the &lt;code&gt;jwt&lt;/code&gt; gem:&lt;/p&gt;

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

def process_token
  jwt_payload = JWT.decode(request.headers['Authorization'].split(' ')[1], Rails.application.secrets.secret_key_base).first
  @current_user_id = jwt_payload['id']
end


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

&lt;/div&gt;

&lt;p&gt;That will work, assuming that there IS an Auth header, and that it has a valid JWT.  I'm not willing to bet that either of these are always going to happen, so let's put some error handling around it.  We want to throw an error if an invalid JWT is sent, but not if there is no Auth header sent at all:&lt;/p&gt;

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

def process_token
  if request.headers['Authorization'].present?
    begin
      jwt_payload = JWT.decode(request.headers['Authorization'].split(' ')[1].remove('"'), Rails.application.secrets.secret_key_base).first
      @current_user_id = jwt_payload['id']
    rescue JWT::ExpiredSignature, JWT::VerificationError, JWT::DecodeError
      head :unauthorized
    end
  end
end


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

&lt;/div&gt;

&lt;p&gt;There!  Now there's just one last step.  We need to make sure that the token is processed before we try to take any other action.  To do this, we just need to add &lt;code&gt;before_action :process_token&lt;/code&gt; underneath &lt;code&gt;respond_to :json&lt;/code&gt;.  Now whenever our app is called, it will process the token (if provided) and &lt;em&gt;then&lt;/em&gt; take whatever action is required.&lt;/p&gt;

&lt;h4&gt;
  
  
  Registrations Controller &amp;lt; Devise::RegistrationsController
&lt;/h4&gt;

&lt;p&gt;Okay, next step is to provide our app the ability to register a new user and assign them a JWT to be passed to our Application Controller for processing. As long as we're just using the default attributes for Devise (and calling them "sign_up_params", we don't need to worry about whitelisting parameters because Devise is already doing it for us.  The reason we need to have our own controller is so that we can have the user instance build its token for the controller to deliver it.  On the client side, we would use this returned token to store in a &lt;code&gt;httpOnly&lt;/code&gt; cookie, &lt;em&gt;(or whatever other storage option you prefer)&lt;/em&gt;.&lt;/p&gt;

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

def create
  user = User.new(sign_up_params)

  if user.save
  token = user.generate_jwt
    render json: token.to_json
  else
    render json: { errors: { 'email or password' =&amp;gt; ['is invalid'] } }, status: :unprocessable_entity
  end
end


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Sessions Controller &amp;lt; Devise::SessionsController
&lt;/h4&gt;

&lt;p&gt;Finally, the last step in our implementation!  Just gotta set up the Sessions Controller so that a user can return and sign back in, and it works the same way as the Registrations Controller.  The user will submit params through the front-end, including their email, which our API will use to query the database and return our user instance.  Then we'll validate that the password they provided matches the stored password and, if successful, we will distribute a JWT:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

def create
  user = User.find_by_email(sign_in_params[:email])

  if user &amp;amp;&amp;amp; user.valid_password?(sign_in_params[:password])
    token = user.generate_jwt
    render json: token.to_json
  else
    render json: { errors: { 'email or password' =&amp;gt; ['is invalid'] } }, status: :unprocessable_entity
  end
end


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;So there it is.  This is how I was finally able to get JWT working with server-side authentication using Devise, the de-facto standard for Rails.  Once I realized that JWT is really a separate process from authenticating credentials, it wasn't so bad to figure out.  Let me know what you think in the comments.  Is there a better way to combine these two gems?  Are there major issues with this implementation?  If you've successfully used &lt;code&gt;devise-jwt&lt;/code&gt;, what is the secret??&lt;/p&gt;

&lt;p&gt;Thanks so much for reading and hanging in there to the end!  Below this is just the final code (minus Gemfile and Initializer), in case you want to see it all in one place.&lt;/p&gt;
&lt;h2&gt;
  
  
  Full Code:
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

# User.rb
class User &amp;lt; ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :recoverable, :rememberable, :validatable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable

  def generate_jwt
    JWT.encode({id: id, exp: 60.days.from_now.to_i}, Rails.application.secrets.secret_key_base)
  end

end


# Routes.rb
Rails.application.routes.draw do
  devise_for :users,
  controllers: {
    registrations: :registrations,
    sessions: :sessions
  }

  root to: "home#index"
end


# Database Schema
  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end


# ApplicationController.rb
class ApplicationController &amp;lt; ActionController::API
  respond_to :json
  before_action :process_token

  private

  # Check for auth headers - if present, decode or send unauthorized response (called always to allow current_user)
  def process_token
    if request.headers['Authorization'].present?
      begin
        jwt_payload = JWT.decode(request.headers['Authorization'].split(' ')[1], Rails.application.secrets.secret_key_base).first
        @current_user_id = jwt_payload['id']
      rescue JWT::ExpiredSignature, JWT::VerificationError, JWT::DecodeError
        head :unauthorized
      end
    end
  end

  # If user has not signed in, return unauthorized response (called only when auth is needed)
  def authenticate_user!(options = {})
    head :unauthorized unless signed_in?
  end

  # set Devise's current_user using decoded JWT instead of session
  def current_user
    @current_user ||= super || User.find(@current_user_id)
  end

  # check that authenticate_user has successfully returned @current_user_id (user is authenticated)
  def signed_in?
    @current_user_id.present?
  end

end


# RegistrationsController.rb
class RegistrationsController &amp;lt; Devise::RegistrationsController

  def create
    user = User.new(sign_up_params)

    if user.save
      token = user.generate_jwt
      render json: token.to_json
    else
      render json: { errors: { 'email or password' =&amp;gt; ['is invalid'] } }, status: :unprocessable_entity
    end
  end

end


# SessionsController.rb
class SessionsController &amp;lt; Devise::SessionsController

  def create
    user = User.find_by_email(sign_in_params[:email])

    if user &amp;amp;&amp;amp; user.valid_password?(sign_in_params[:password])
      token = user.generate_jwt
      render json: token.to_json
    else
      render json: { errors: { 'email or password' =&amp;gt; ['is invalid'] } }, status: :unprocessable_entity
    end
  end

end


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

&lt;/div&gt;

</description>
      <category>rails</category>
      <category>authentication</category>
      <category>jwt</category>
      <category>devise</category>
    </item>
    <item>
      <title>Rails SQL Injections</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 28 Nov 2020 03:35:29 +0000</pubDate>
      <link>https://dev.to/dhintz89/rails-sql-injections-451e</link>
      <guid>https://dev.to/dhintz89/rails-sql-injections-451e</guid>
      <description>&lt;p&gt;When studying backend development, I learned that using SQL (and other database querying languages) directly will result in much faster code.  SQL is built specifically for querying, so it certainly makes sense, but I've never actually verified if this was in fact true and, if it is, how much faster it is.  So, I decided to put it to the test and I created a mini-project in Ruby on Rails to validate the hypothesis that my code will run faster, all else being equal, if I use a direct SQL injection rather than a Ruby-ActiveRecord based approach.  Here's what happened.&lt;/p&gt;

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

&lt;p&gt;First thing, I needed to create my test scenario and then implement a SQL and an ActiveRecord implementation that gets me to the same result.  I'm not going to go through the steps to create the project, but here are the highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users and associated Orders are stored in the database&lt;/li&gt;
&lt;li&gt;Orders have a payer_name and created_at attribute&lt;/li&gt;
&lt;li&gt;In the Order Model, I have a method to &lt;strong&gt;extract&lt;/strong&gt; the orders associated to a given user, and &lt;strong&gt;sort&lt;/strong&gt; them by created_at&lt;/li&gt;
&lt;li&gt;Optionally, I can &lt;strong&gt;filter&lt;/strong&gt; the results by specifying a payer_name when calling the method&lt;/li&gt;
&lt;li&gt;My demo user will have 10 associated orders&lt;/li&gt;
&lt;li&gt;6 of these orders have a payer_name equal to "Store1"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After setting up my app and database, I need to code the method described in the above bullets.&lt;/p&gt;

&lt;h4&gt;
  
  
  Regular Implementation (Ruby &amp;amp; ActiveRecord)
&lt;/h4&gt;

&lt;p&gt;Here's what this code looks like &lt;strong&gt;without&lt;/strong&gt; directly injecting SQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def self.sort_orders(user_id, payer_name = '*')
  if payer_name == '*'
    User.find(user_id).orders.sort {|a, b| a.created_at &amp;lt;=&amp;gt; b.created_at}
  else
    User.find(user_id).orders.filter{|t| t.payer_name == payer_name}.sort {|a, b| a.created_at &amp;lt;=&amp;gt; b.created_at}
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, regardless of whether a payer_name is specified, the code starts by finding the User instance based on the passed-in user_id, then it finds all the orders that are associated.  &lt;strong&gt;IF&lt;/strong&gt; a payer_name is specified, the results are filtered at this point to only include results where payer_name matches what was provided.  Finally, any remaining results are sorted in ascending order by created_at.&lt;/p&gt;

&lt;p&gt;Note that, if a payer_name is specified, I filter the results BEFORE sorting.  This will help my performance a little bit and make the test more fair.&lt;/p&gt;

&lt;h4&gt;
  
  
  SQL Injection Implementation
&lt;/h4&gt;

&lt;p&gt;Now, I want to add a method that does &lt;em&gt;exactly&lt;/em&gt; the same thing, but this time I'll retrieve the results with SQL instead of relying on Ruby and ActiveRecord.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def self.sort_orders_SQL(user_id, payer_name = '*')
  if payer_name == '*'
    self.find_by_sql(["SELECT * FROM orders WHERE user_id = ? ORDER BY created_at ASC", user_id].flatten)
  else
    self.find_by_sql(["SELECT * FROM orders WHERE user_id = ? AND payer_name = ? ORDER BY created_at ASC", user_id, payer_name].flatten)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As stated above, this does the exact same thing.  One major advantage; however, is that I can add the order logic in the SQL query, avoiding an iterator function altogether.  Same deal for the filter logic if a payer_name is specified.  This is an excellent use case for injecting a database query!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Test
&lt;/h2&gt;

&lt;p&gt;Now that I'm all set up, let's get to testing.  For this, I'll use a ruby gem called &lt;a href="https://github.com/ruby/benchmark"&gt;benchmark&lt;/a&gt; to calculate how much time it takes to run each method.  Since these are not huge methods, I'll run them each many times so that my results can be more easily operated on &lt;em&gt;(I don't want to type that many ".000000"s if I don't have to)&lt;/em&gt;.  I'll use the &lt;code&gt;bm&lt;/code&gt; method to run both tests at the same time.  I'll start by running each method 1000 times, then just for fun, I'll run the same test method with 5,000 and 10,000 repetitions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Testing Without 'payer_name' Filter
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Benchmark.bm do |benchmark|
  benchmark.report("no-inject") do  // label denoting no SQL injection
    1000.times do
      Order.sort_orders(User.first.id)
    end
  end

  benchmark.report("injectSQL") do  // label denoting SQL injection used
    1000.times do
      Order.sort_orders_SQL(User.first.id)
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the test 1,000 times each results in the following data (&lt;em&gt;Note: Reduction column is calculated, not provided by benchmark gem&lt;/em&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;0.421875&lt;/td&gt;
&lt;td&gt;1.609375&lt;/td&gt;
&lt;td&gt;2.03125&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;0.203125&lt;/td&gt;
&lt;td&gt;0.5&lt;/td&gt;
&lt;td&gt;0.703125&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;51.85%&lt;/td&gt;
&lt;td&gt;68.93%&lt;/td&gt;
&lt;td&gt;65.38%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;5,000 repetitions resulted in the following data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;0.828125&lt;/td&gt;
&lt;td&gt;3.21875&lt;/td&gt;
&lt;td&gt;4.046875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;0.6875&lt;/td&gt;
&lt;td&gt;2.078125&lt;/td&gt;
&lt;td&gt;2.765625&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;16.98%&lt;/td&gt;
&lt;td&gt;35.44%&lt;/td&gt;
&lt;td&gt;31.66%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally 10,000 repetitions resulted in the following data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;1.890625&lt;/td&gt;
&lt;td&gt;6.234375&lt;/td&gt;
&lt;td&gt;8.125000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;1.156250&lt;/td&gt;
&lt;td&gt;2.625000&lt;/td&gt;
&lt;td&gt;3.781250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;38.84%&lt;/td&gt;
&lt;td&gt;57.89%&lt;/td&gt;
&lt;td&gt;53.46%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Testing With 'payer_name' Filter
&lt;/h4&gt;

&lt;p&gt;Now, adding the criteria that I only want to return orders where payer_name is Store1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Benchmark.bm do |benchmark|
  benchmark.report("no-inject") do  // label denoting no SQL injection
    1000.times do
      Order.sort_orders(User.first.id, "Store1")
    end
  end

  benchmark.report("injectSQL") do  // label denoting SQL injection used
    1000.times do
      Order.sort_orders_SQL(User.first.id, "Store1")
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the test 1,000 times each results in the following data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;0.390625&lt;/td&gt;
&lt;td&gt;0.9375&lt;/td&gt;
&lt;td&gt;1.328125&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;0.09375&lt;/td&gt;
&lt;td&gt;0.203125&lt;/td&gt;
&lt;td&gt;0.296875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;76.00%&lt;/td&gt;
&lt;td&gt;78.33%&lt;/td&gt;
&lt;td&gt;77.65%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;5,000 repetitions resulted in the following data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;1.234375&lt;/td&gt;
&lt;td&gt;3.59375&lt;/td&gt;
&lt;td&gt;4.828125&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;1.0625&lt;/td&gt;
&lt;td&gt;1.3125&lt;/td&gt;
&lt;td&gt;2.375&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;13.92%&lt;/td&gt;
&lt;td&gt;63.48%&lt;/td&gt;
&lt;td&gt;50.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally 10,000 repetitions resulted in the following data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;3.28125&lt;/td&gt;
&lt;td&gt;11.359375&lt;/td&gt;
&lt;td&gt;14.640625&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;1.96875&lt;/td&gt;
&lt;td&gt;4.203125&lt;/td&gt;
&lt;td&gt;6.171875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;40.00%&lt;/td&gt;
&lt;td&gt;63.00%&lt;/td&gt;
&lt;td&gt;57.84%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;With this data, the hypothesis that direct SQL injection will work faster than Ruby &amp;amp; ActiveRecord is, in fact, supported.  Additionally, when looking at the reduction figures, they suggest that it's actually exceedingly faster!  It's important to keep in mind that there are other factors effecting the results, including what programs are running on my computer, so running the same test twice is highly unlikely to get the same results.  However; with an average reduction of 50.17% for non-filtered, and a whopping 62.10% for filtered results, there is no question that this SQL injection strategy is a huge performance boost in the right circumstance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus
&lt;/h2&gt;

&lt;p&gt;There was something that was bothering me about my analysis above.  The SQL strategy was a huge performance boost, &lt;em&gt;BUT&lt;/em&gt; it has the benefit of skipping iterator methods, which will certainly give it the edge.  To measure the effect of purely SQL vs ActiveRecord, I need to cut out that mediating factor.  So here is the table of results for the same test, but with all sorting and filtering removed.  This is simply finding the user based on the user_id, and getting all associated orders in no particular order.  &lt;/p&gt;

&lt;p&gt;I ran the test with 5,000 iterations.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;System CPU Time&lt;/th&gt;
&lt;th&gt;User CPU Time&lt;/th&gt;
&lt;th&gt;Total CPU Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;no-inject&lt;/td&gt;
&lt;td&gt;1.96875&lt;/td&gt;
&lt;td&gt;4.28125&lt;/td&gt;
&lt;td&gt;6.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;injectSQL&lt;/td&gt;
&lt;td&gt;1.171875&lt;/td&gt;
&lt;td&gt;2.546875&lt;/td&gt;
&lt;td&gt;3.71875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reduction&lt;/td&gt;
&lt;td&gt;40.48%&lt;/td&gt;
&lt;td&gt;40.51%&lt;/td&gt;
&lt;td&gt;40.50%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Okay, so this suggests that there is still a massive, if slightly smaller, performance gain from directly using SQL over ActiveRecord.  Hypothesis still supported.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>sql</category>
      <category>performance</category>
    </item>
    <item>
      <title>Functions Creating Functions!</title>
      <dc:creator>Daniel Hintz</dc:creator>
      <pubDate>Sat, 21 Nov 2020 00:23:56 +0000</pubDate>
      <link>https://dev.to/dhintz89/functions-creating-functions-3ap2</link>
      <guid>https://dev.to/dhintz89/functions-creating-functions-3ap2</guid>
      <description>&lt;p&gt;Hi there!  This goes through how to do this in JavaScript.  I also wrote a &lt;a href="https://dev.to/dhintz89/functions-creating-functions-ruby-edition-1j1a"&gt;sister-article&lt;/a&gt; that goes through how to do the same thing in Ruby.&lt;/p&gt;

&lt;p&gt;We all know what a programming function is and what it does.  It encapsulates a particular behavior.  For example, this function divides any number you'd like by 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function divideBy5(number) {
  return number / 5;
}

divideBy5(15)
  // =&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in life, we often see different variations of a complex behavior, and this is a situation we see a lot in programming as well.  For example, imagine we wanted to add some complexity to the above function so that it only divides numbers that are cleanly divisible by 5.  We could easily do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function divideBy5(number) {
  if(number % 5 === 0) {
    return number / 5;
  }
  return `${number} is not divisible by 5!`;
}

divideBy5(15)
  // =&amp;gt; 3
divideBy5(7)
  // =&amp;gt; "7 is not divisible by 5!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we might need to similarly divide by other numbers later on in our program.  We could write a new function for each number, but that would be a pain.  Instead, let's create a function which in turn creates &lt;em&gt;other&lt;/em&gt; functions!&lt;/p&gt;

&lt;p&gt;To do this, we'll create a wrapper function, this is where we'll set up our flexibility by passing an argument.  This argument will represent the variation in the behavior; in our simple case, it's a specific divisor.  We want to be able to divide by 5, or 8, or 100, or whatever else our hearts desire, so we'll call this argument &lt;code&gt;divisor&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 DivideBy(divisor) {
  // the rest of the function will go here.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we know that the output of the function needs to be a different function, so our return value will need to be a function declaration.  There's no need for this inner function to have a name, so we'll create an anonymous function that takes in an argument - this will be the number that we want evaluated (15 in our first example).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function DivideBy(divisor) {
  return function(number) {
    // the rest of the function will go here
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can add in our main functionality, which was defined in our &lt;code&gt;divideBy5()&lt;/code&gt; example, but we now get to parameterize BOTH the numerator that we want evaluated, AND the divisor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function DivideBy(divisor) {
  return function(number) {
    if(number % divisor === 0) {
      return number / divisor;
    }
    return `${number} is not divisible by ${divisor}!`;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great!  Now if we call &lt;code&gt;DivideBy(5)&lt;/code&gt;, we get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ƒ (number) {
    if(number % divisor === 0) {
      return number / divisor;
    }
    return `${number} is not divisible by ${divisor}!`;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...I know what you're thinking - "What's this? What are we supposed to do with it?"  And the answer is deceptively simple: just name it!  That output is a function which is asking for a number to divide by the divisor that we just passed in (5).  So we create a function expression so we can reference it later: &lt;code&gt;const DivideByFive = DivideBy(5)&lt;/code&gt; and we now have the same function as our divideBy5(number) function from before.  We can call it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DivideByFive(15)
  // =&amp;gt; 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit of this pattern is that we can now assign this behavior to any divisor/number variation.  As the complexity of the behavior goes up, this becomes more and more useful.&lt;br&gt;&lt;br&gt;
Here's the full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function DivideBy(divisor) {
  return function(number) {
    if(number % divisor === 0) {
      return number / divisor;
    }
    return `${number} is not divisible by ${divisor}!`;
  }
}

const DivideByFive = DivideBy(5);
  // =&amp;gt; undefined
const divBy8 = DivideBy(8);
  // =&amp;gt; undefined
const divideNumberBy100 = DivideBy(100);
  // =&amp;gt; undefined

DivideByFive(15)
  // =&amp;gt; 3

DivideByFive(8)
  // =&amp;gt; "8 is not divisible by 5!"

divideNumberBy100(500)
  // =&amp;gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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