<?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: Alec Grey</title>
    <description>The latest articles on DEV Community by Alec Grey (@alecgrey).</description>
    <link>https://dev.to/alecgrey</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%2F493019%2F20da94e7-d922-4dd9-916a-e2b2ec4165c2.jpeg</url>
      <title>DEV Community: Alec Grey</title>
      <link>https://dev.to/alecgrey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alecgrey"/>
    <language>en</language>
    <item>
      <title>Controlled Forms with Frontend Validations using React-Bootstrap</title>
      <dc:creator>Alec Grey</dc:creator>
      <pubDate>Fri, 29 Jan 2021 22:05:54 +0000</pubDate>
      <link>https://dev.to/alecgrey/controlled-forms-with-front-and-backend-validations-using-react-bootstrap-5a2</link>
      <guid>https://dev.to/alecgrey/controlled-forms-with-front-and-backend-validations-using-react-bootstrap-5a2</guid>
      <description>&lt;p&gt;I've been working on my capstone project for the last couple of weeks, and with it I've had a chance to learn a lot more about react-bootstrap for putting together functional, and aesthetically pleasing web pages.  One place that this framework has really helped me to up my game is in creating responsive forms.  Pairing with React hooks, you can very easily make forms that store input in state, keep control form values, and display invalidations when necessary.  Lets create a simple form with react &amp;amp; react-bootstrap to see how it's done!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AlecGrey/demo-form-for-blog" rel="noopener noreferrer"&gt;Link to Repo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  App Setup
&lt;/h3&gt;

&lt;p&gt;We're going to build a simple form with a few fields.  To start, lets initialize our app with &lt;code&gt;npx create-react-app form-demo&lt;/code&gt;.  Next we're going to add react-bootstrap to our project with either &lt;code&gt;npm install --save react-bootstrap&lt;/code&gt; or &lt;code&gt;yarn add react-bootstrap&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Because React-Bootstrap comes with specific out-of-the-box styling, it is also helpful to add vanilla-bootstrap for additional customization.  To do this, start with either &lt;code&gt;npm install --save bootstrap&lt;/code&gt;, or &lt;code&gt;yarn add bootstrap&lt;/code&gt;, then import it into your index.js or App.js files:&lt;/p&gt;

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

&lt;span class="c1"&gt;// ./src/App.js&lt;/span&gt;
&lt;span class="c1"&gt;// ...other imports&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap/dist/css/bootstrap.min.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now that our app is set up, we can start building out our basic form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Building with React-Bootstrap
&lt;/h3&gt;

&lt;p&gt;Like all components, we need to use &lt;code&gt;import&lt;/code&gt; in order to bring them in for availability in our app.  Now that we have the library installed, we can easily add react-bootstrap components to our app:&lt;/p&gt;

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

&lt;span class="c1"&gt;// ./src/App.js&lt;/span&gt;
&lt;span class="c1"&gt;// ...other imports&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-bootstrap/Form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This convention is consistent throughout the library, but I highly suggest reviewing the &lt;a href="https://react-bootstrap.github.io/components/alerts/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for specific import instructions.&lt;/p&gt;

&lt;p&gt;Building the form follows very straightforward convention, but also keeps room open for styling choices to be mixed in.  Here is the code for our form, which will be used to review food items at a restaurant:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;App d-flex flex-column align-items-center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;How&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;dinner&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;300px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Group&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Food&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Select&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/option&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chicken parm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Chicken&lt;/span&gt; &lt;span class="nx"&gt;Parm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/option&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BLT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;BLT&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/option&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;steak&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Steak&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/option&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;salad&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Salad&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/option&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Control&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Group&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Rating&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Group&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Comments&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textarea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Group&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt; &lt;span class="nx"&gt;Review&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Lets break this down:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Following React convention, we have the div wrapping the rest of the component.&lt;/li&gt;
&lt;li&gt;We wrap the entire form in a single &lt;code&gt;Form&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;Each field is &lt;em&gt;grouped&lt;/em&gt; using the &lt;code&gt;Form.Group&lt;/code&gt; component wrapper.  This generally follows a 1:1 rule for Group:Field, but there are advanced cases such as having multiple fields on a single row where you could wrap multiple fields.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Form.Label&lt;/code&gt; for labelling each field.  You can use added styling on the form group in order to make this display inline with your form input, but by default they will stack vertically.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Form.Control&lt;/code&gt; to designate the input field.  Here we have a couple of options for inputs.  If your field resembles an HTML input tag, you can use &lt;code&gt;type='type'&lt;/code&gt; to determine what type of input field it will be.  In our example we use &lt;code&gt;type='text'&lt;/code&gt; and &lt;code&gt;type='number'&lt;/code&gt;.  If you will be using another HTML tag, such as a &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; tag, you can use the &lt;code&gt;as='tag'&lt;/code&gt; designation to determine what you get.  In our example we use both an &lt;code&gt;as='select'&lt;/code&gt; and an &lt;code&gt;as='textarea'&lt;/code&gt; to designate these.&lt;/li&gt;
&lt;li&gt;To submit the form, we add a button to the bottom with a &lt;code&gt;type='submit'&lt;/code&gt; designation.  Personally, I prefer not to use the 'submit' type, as we will more than likely be overriding the default submit procedure anyway.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, we can very quickly build a form that is aesthetically pleasing, but the important next step is to make it functional!&lt;/p&gt;
&lt;h3&gt;
  
  
  Updating State with Form Input
&lt;/h3&gt;

&lt;p&gt;Using react hooks, we're going to create 2 pieces of state: the &lt;code&gt;form&lt;/code&gt; and the &lt;code&gt;errors&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setForm&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setErrors&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;form&lt;/code&gt; object will hold a key-value pair for each of our form fields, and the &lt;code&gt;errors&lt;/code&gt; object will hold a key-value pair for each error that we come across on form submission.&lt;/p&gt;

&lt;p&gt;To update the state of &lt;code&gt;form&lt;/code&gt;, we can write a simple function:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This will update our state to keep all the current form values, then add the newest form value to the right key location.&lt;/p&gt;

&lt;p&gt;We can now add callback functions for &lt;code&gt;onChange&lt;/code&gt; on each form field:&lt;/p&gt;

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

&lt;span class="c1"&gt;// do for each Form.Control:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;As you can see, we are setting the key of 'name' to the value of the input field.  If your form will be used to create a new instance in the backend, it is a good idea to set the key to the name of the field that it represents in the database.&lt;/p&gt;

&lt;p&gt;Great!  Now we have a form that updates a state object when you change the value.  Now what about when we submit the form?&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking for errors on submit
&lt;/h3&gt;

&lt;p&gt;We now need to check our form for errors!  Think about what we &lt;strong&gt;don't&lt;/strong&gt; want our backend to receive as data, and come up with your cases.  In our form, we don't want&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blank or null values&lt;/li&gt;
&lt;li&gt;Name must be less than 30 characters&lt;/li&gt;
&lt;li&gt;Ratings above 5 or less than 1&lt;/li&gt;
&lt;li&gt;Comments greater than 100 characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using these cases, we're going to create a function that checks for them, then constructs an &lt;code&gt;errors&lt;/code&gt; object with error messages:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findFormErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;food&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="c1"&gt;// name errors&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cannot be blank!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name is too long!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="c1"&gt;// food errors&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;food&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;food&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;food&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select a food!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="c1"&gt;// rating errors&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;must assign a rating between 1 and 5!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="c1"&gt;// comment errors&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cannot be blank!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment is too long!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Perfect.  Now when we call this, we will be returned an object with all the errors in our form.&lt;/p&gt;

&lt;h4&gt;
  
  
  Let's handle submit now, and check for errors.  Here is our order of operations:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Prevent default action for a form using &lt;code&gt;e.preventDefault()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check our form for errors, using our new function&lt;/li&gt;
&lt;li&gt;If we receive errors, update our state accordingly, otherwise proceed with form submission!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;now to handle submission:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// get our new errors&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findFormErrors&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Conditional logic:&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// We got errors!&lt;/span&gt;
      &lt;span class="nf"&gt;setErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newErrors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// No errors! Put any logic here for the form submission!&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Thank you for your feedback!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;By using &lt;code&gt;Object.keys(newErrors).length &amp;gt; 0&lt;/code&gt; we are simply checking to see if our object has any key-value pairs, or in other words, did we add any errors.&lt;/p&gt;

&lt;p&gt;Now that we have errors, we need to display them in our form!  This is where we will add our last bit of React-Bootstrap spice: &lt;code&gt;Form.Control.Feedback&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Invalidations and Feedback
&lt;/h3&gt;

&lt;p&gt;React bootstrap allows us to add a feedback field, and to tell it &lt;em&gt;what&lt;/em&gt; and &lt;em&gt;when&lt;/em&gt; to display information.&lt;/p&gt;

&lt;p&gt;On each of our forms, we will add an &lt;code&gt;isInvalid&lt;/code&gt; boolean, and a React-Bootstrap Feedback component tied to it:&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Label&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt; 
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;isInvalid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Feedback&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;invalid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Control.Feedback&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Form.Group&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;With this added, Bootstrap will highlight the input box red upon a true value for &lt;code&gt;isInvalid&lt;/code&gt;, and will display the error in &lt;code&gt;Form.Control.Feedback&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's one final step however!  We need to &lt;em&gt;reset&lt;/em&gt; our error fields once we have addressed the errors.  My solution for this is to update the errors object in tandem with form input, like so:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// Check and see if errors exist, and remove them from the error object:&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setErrors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, when a new input is added to the form, we will reset the errors at that place as well.  Then on the next form submission, We can check for errors again!&lt;/p&gt;

&lt;h3&gt;
  
  
  Final product in action:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Faw9p9jfwhrdaqjeqwmqv.gif" 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%2Faw9p9jfwhrdaqjeqwmqv.gif" alt="Demonstration gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! I hope this was helpful.&lt;/p&gt;

</description>
      <category>react</category>
      <category>bootstrap</category>
      <category>forms</category>
      <category>validations</category>
    </item>
    <item>
      <title>My Tech Resolutions for 2021</title>
      <dc:creator>Alec Grey</dc:creator>
      <pubDate>Tue, 05 Jan 2021 05:24:07 +0000</pubDate>
      <link>https://dev.to/alecgrey/my-tech-resolutions-for-2021-3b84</link>
      <guid>https://dev.to/alecgrey/my-tech-resolutions-for-2021-3b84</guid>
      <description>&lt;p&gt;Last week I had some well-needed rest from my coding bootcamp with Flatiron.  While I tried my best to stay off the code editor, I did spend a few hours here and there, and ended up spending more time than I should have watching tech-related youtube videos... One video that caught my attention the most was &lt;a href="https://www.youtube.com/watch?v=oHtR5YSPLjo"&gt;this video&lt;/a&gt; regarding tech trends &amp;amp; predictions for 2021. &lt;/p&gt;

&lt;p&gt;Now that I'm less than a month away from the end of my bootcamp, the thought of entering the job market has become all too real, and it made me think a lot about what I'm going to have to &lt;em&gt;teach myself&lt;/em&gt; once the guided work ends.  In that regard, I thought it would be helpful to write out some &lt;strong&gt;tech resolutions for 2021&lt;/strong&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Learn C++
&lt;/h2&gt;

&lt;p&gt;It's often said that learning coding fundamentals and concepts is much more important than learning languages, and I 100% agree.  However, I've also heard that it is valuable to learn at least one lower-level language, and I've &lt;em&gt;also&lt;/em&gt;, also heard that it is valuable to learn a form of C.  Because of that, I've added C++ to the top of my list of languages to dive into for 2021.&lt;/p&gt;

&lt;p&gt;C++ has a reputation for being one of the most difficult languages to pick up, an idea which is summed up great &lt;a href="https://adamtcroft.com/why-c-is-so-hard-to-learn/"&gt;this article&lt;/a&gt;.  Here's a great excerpt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"With C++ you really need to know what and why you and the computer are doing what you’re doing.&lt;/p&gt;

&lt;p&gt;This can be thrown in contexts of 'efficient operations' or 'garbage collection' or 'memory management' or whatever – but it all boils down to the same idea at the end of the day."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Long-story-short, C++ gives you a lot of power and freedom when it comes to data management, storage, and in what coding paradigms you follow, but that also means you'll need a stronger understanding of computer science to succeed.  I for one am excited to see what great and terrible things I do to my Macbook while I figure this all out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/sololearn/reasons-to-love-c-11c7c2f23d88"&gt;Here is a great blog&lt;/a&gt; if you need some good C-heerleading.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Develop a full-stack MERN application
&lt;/h2&gt;

&lt;p&gt;MERN is one of those cool buzzwords that you see online a lot, and there are plenty of great tutorials that can help you on the path to building your own MERN application.&lt;/p&gt;

&lt;p&gt;MERN stands for: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;M&lt;/strong&gt;ongo DB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E&lt;/strong&gt;xpress JS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R&lt;/strong&gt;eact JS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;N&lt;/strong&gt;ode JS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a back-to-front Javascript application.  One of the big takeaways I gleaned from the 2021 trends/predictions is the general plateau-ing of Javascript as a language, and how it's actually a pretty cool thing.  Javascript is not going away any time soon, and there are supposedly fewer and fewer big updates to be made.&lt;/p&gt;

&lt;p&gt;Key things to know about each of the technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB&lt;/strong&gt; - Data is stored in a NoSQL format, meaning that instead of database tables with rows and columns, you have documents inside of collections, each with data stored in JSON objects!  Because we utilize this data structure, we can store more powerful data such as arrays!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ExpressJS&lt;/strong&gt; - A backend-oriented framework for NodeJS.  It can be used to build multi-page web applications, following a model-view-controller structure, but is more commonly used to develop a backend-API to use alongside...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ReactJS&lt;/strong&gt; - Arguably the most popular front-end JS framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NodeJS&lt;/strong&gt; - A runtime environment for Javascript, allowing it to be executed outside of the browser.  It's the &lt;em&gt;glue&lt;/em&gt; of the whole application!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a sidenote - this is also a great time to learn Typescript as well...&lt;/p&gt;

&lt;h2&gt;
  
  
  3. React Native &lt;strong&gt;&lt;em&gt;- or -&lt;/em&gt;&lt;/strong&gt; Flutter
&lt;/h2&gt;

&lt;p&gt;I've flip-flopped on this many times in the last few months, and I'm leaning towards React Native at the moment.  &lt;a href="https://nevercode.io/blog/flutter-vs-react-native-a-developers-perspective/"&gt;Here&lt;/a&gt; is a fantastic article that compares the two platforms in depth (spoiler alert-&lt;strong&gt;Flutter&lt;/strong&gt; won).&lt;/p&gt;

&lt;p&gt;What are the benefits of learning &lt;em&gt;either&lt;/em&gt; platform?  They both allow users to develop &lt;strong&gt;cross-platform&lt;/strong&gt; applications, using a single codebase.  This cuts down a lot of time and energy wasted learning one language for iOS and another for Android development.  Time is money, and since I'm planning my next mobile-app like a career criminal going back in for &lt;em&gt;'one last job'&lt;/em&gt;, I'm expecting a huge return on investment.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A Testing Framework
&lt;/h2&gt;

&lt;p&gt;Honestly, I can't tell if this will be me favorite or least-favorite technology I learn this year, but I have a feeling it will be one of them.  I recently had my first experience in automation, creating a web-scraping script to grab apartment listings off of Craigslist.  If using a testing framework is &lt;em&gt;anything&lt;/em&gt; like that, I'll be looking forward to it.  &lt;/p&gt;

&lt;p&gt;The frontrunner for me is &lt;strong&gt;Jest&lt;/strong&gt;.  It's one of the strongest contenders for JS testing frameworks, and it's built with React in mind.  &lt;/p&gt;

&lt;h4&gt;
  
  
  This list could go on forever...
&lt;/h4&gt;

&lt;p&gt;There are a ton of things I would love to learn this year, but those are the top 4 on my list.  I'm sure at least 3 will change by March.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quick Guide to PDF generation in Ruby</title>
      <dc:creator>Alec Grey</dc:creator>
      <pubDate>Mon, 30 Nov 2020 21:05:31 +0000</pubDate>
      <link>https://dev.to/alecgrey/quick-guide-to-pdf-generation-in-ruby-2h88</link>
      <guid>https://dev.to/alecgrey/quick-guide-to-pdf-generation-in-ruby-2h88</guid>
      <description>&lt;p&gt;I recently learned about some additional controller functionality that expanded beyond the simple &lt;code&gt;render 'view'&lt;/code&gt; that I used in my first Rails project.  Since my project had to do with generating lists for a user, I was understandably excited when I learned about the &lt;code&gt;send_file&lt;/code&gt; method.  The possibility of sending a user data via a PDF was always a stretch-goal, but I had no idea where to start.&lt;/p&gt;

&lt;p&gt;Though the &lt;code&gt;send_file&lt;/code&gt; method gave me a good starting point, I still had a huge issue: &lt;strong&gt;&lt;em&gt;how do I create a custom PDF?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Luckily, with some google-magic, I stumbled on some great articles that helped me out, particularly &lt;a href="https://thoughtbot.com/upcase/videos/generating-pdfs-with-rails" rel="noopener noreferrer"&gt;this great video from Upcase&lt;/a&gt;.  We're going to look specifically at creating custom PDFs, but I'd highly suggest checking out the video for a more in-depth look at adding this to your own Rails project&lt;/p&gt;

&lt;h3&gt;
  
  
  Where We're Going
&lt;/h3&gt;

&lt;p&gt;We're going to take a look at the process for setting up creating a custom PDF in Ruby, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tools/gem dependencies needed&lt;/li&gt;
&lt;li&gt;How to use the tools to generate a simple test PDF&lt;/li&gt;
&lt;li&gt;Customizing the layout/data of your PDF&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools / Gems
&lt;/h3&gt;

&lt;p&gt;To get started, we are going to need to install wkhtmltopdf.  In your terminal, use brew to complete the install process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; wkhtmltopdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;wkhtmltopdf&lt;/strong&gt; is a straightforward tool that works by taking HTML and CSS, and converting it into a PDF document.&lt;/p&gt;

&lt;p&gt;Unfortunately, wkhtmltopdf cannot be used directly in our Ruby application.  This is where we will need the &lt;code&gt;PDFKit&lt;/code&gt; gem.  Either install globally, or add it to your gemfile in a rails application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;pdfkit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating a simple test PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PDFKit&lt;/strong&gt; allows us access to very simply take a string of HTML code, and convert it into a PDF document, that we can download to a file location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'pdfkit'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_pdf_from_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PDFKit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;kit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With our basic PDF converter method defined, let's give it some data and see what happens!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;h1&amp;gt;Hello, Globe!&amp;lt;/h1&amp;gt;'&lt;/span&gt;
&lt;span class="n"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'./hello.pdf'&lt;/span&gt;

&lt;span class="n"&gt;generate_pdf_from_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this application, I now should have a &lt;em&gt;new&lt;/em&gt; pdf document in the current directory with the name &lt;strong&gt;hello.pdf&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmxa5z69z2n9s2tx3oraw.gif" 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%2Fmxa5z69z2n9s2tx3oraw.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Spruce things up with CSS!
&lt;/h3&gt;

&lt;p&gt;The great thing about this process is that &lt;strong&gt;wkhtmltopdf&lt;/strong&gt; and &lt;strong&gt;PDFKit&lt;/strong&gt; can take any viable HTML and convert it to PDF format.  Let's take advantage of that by adding &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; to the head of our HTML!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"
    &amp;lt;head&amp;gt;
        &amp;lt;style&amp;gt;
            body {
                text-align: center;
                background-color: gray;
            }
            h1 {
                color: white;
            }
        &amp;lt;/style&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;h1&amp;gt;Doggos are cool&amp;lt;/h1&amp;gt;
        &amp;lt;p&amp;gt;I like doggos, they are very cool.&amp;lt;/p&amp;gt;
    &amp;lt;/body
    "&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we run our application again, we will get a stylized PDF as the result!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpufrztxavsrwpmhdohjr.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%2Fpufrztxavsrwpmhdohjr.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep in mind, these all default to an 8.5 x 11 document, which is convenient for if we want to make anything printable!&lt;/p&gt;

&lt;p&gt;I hope this helps add a nifty tool to your belt.  Again, I would highly suggest watching &lt;a href="https://thoughtbot.com/upcase/videos/generating-pdfs-with-rails" rel="noopener noreferrer"&gt;this video from Upcase&lt;/a&gt;, which gives an in-depth look at integrating this functionality into a Rails application.&lt;/p&gt;

&lt;p&gt;Cheers.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>Yield</title>
      <dc:creator>Alec Grey</dc:creator>
      <pubDate>Tue, 10 Nov 2020 21:10:30 +0000</pubDate>
      <link>https://dev.to/alecgrey/yield-3gl3</link>
      <guid>https://dev.to/alecgrey/yield-3gl3</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Of the many things I take for granted as a beginner Rubyist, I think the concept I've taken for granted the most is &lt;strong&gt;code blocks&lt;/strong&gt;, and the keyword &lt;code&gt;yield&lt;/code&gt;.  I assumed that &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; were just inherent parts of enumerables, conditional statements, and forms.  &lt;/p&gt;

&lt;p&gt;The truth is, we can take advantage of these code blocks in our own methods, and access them with the keyword &lt;code&gt;yield&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;strong&gt;&lt;em&gt;yield&lt;/em&gt;&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;yield&lt;/code&gt; is a built-in Ruby &lt;em&gt;keyword&lt;/em&gt;.  A list of all Ruby keywords can be found &lt;a href="https://docs.ruby-lang.org/en/2.2.0/keywords_rdoc.html"&gt;here&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;When &lt;code&gt;yield&lt;/code&gt; is interpreted, it begins the execution of the code-block that directly succeeds the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_block&lt;/span&gt;
   &lt;span class="k"&gt;yield&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;execute_block&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="s2"&gt;"Hello"&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; nil&lt;/span&gt;

&lt;span class="n"&gt;execute_block&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; 
&lt;span class="c1"&gt;#=&amp;gt; 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we have a method that simply executes the code block it is given.  When the &lt;code&gt;yield&lt;/code&gt; keyword is hit, the method is paused, and the block is ran.  The result of the block gets returned to the method, and execution can continue.&lt;/p&gt;

&lt;p&gt;Now that we've seen the basic idea of blocks &amp;amp; &lt;code&gt;yield&lt;/code&gt;, let's look at some cool implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance testing
&lt;/h3&gt;

&lt;p&gt;A common use for a custom &lt;code&gt;yield&lt;/code&gt; method is when performance testing a method or block of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;speedtest&lt;/span&gt;
    &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method will take a time-stamp before and after the execution of a block.  It will take the difference of those times to find the runtime, then return the result of the code-block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;speedtest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;1.0e-06&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;speedtest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(:&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;3.0e-06&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Customized Conditional-flow
&lt;/h3&gt;

&lt;p&gt;Let's make our own conditional flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allow_if_true&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;false_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;false_message&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="nb"&gt;method&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this method, we limit the execution of &lt;code&gt;method&lt;/code&gt;, so that it only runs if the given block returns &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;allow_if_true&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top_secret_internet_stuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Access Denied"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:username&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Bill Gates"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can successfully keep safe all of the internet's deep dark secrets.  Take &lt;strong&gt;that&lt;/strong&gt; hackers!&lt;/p&gt;

&lt;h3&gt;
  
  
  What about enumerating?
&lt;/h3&gt;

&lt;p&gt;Fun fact: We can pass parameters to our &lt;code&gt;yield&lt;/code&gt;!  Let's take a look at how we can use that by making our own &lt;strong&gt;each&lt;/strong&gt;-like enumerator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_stuff_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"not an array!"&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;
   &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
   &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="n"&gt;arr&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this simple implementation, we&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First assure we have the right data-type with &lt;code&gt;unless&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Iterate over the array with a &lt;code&gt;while&lt;/code&gt; loop &amp;amp; &lt;code&gt;count&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display the original array at the end.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;do_stuff_to&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you notice the &lt;code&gt;|i|&lt;/code&gt;?  When we pass a value to yield, we denote it's presence by declaring it in pipe-notation in the block.  Just like our built-in enumerable methods, we have a parameter for each value passed to the yield.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing
&lt;/h3&gt;

&lt;p&gt;To be completely honest, at this point I don't know how useful a custom &lt;code&gt;yield&lt;/code&gt; method will be to your day-to-day development.  But at the very least, I hope this helps de-mystify this concept to you, and that you'll be more comfortable knowing what goes on when you see these come up.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>methods</category>
    </item>
    <item>
      <title>.reduce: a versatile array method</title>
      <dc:creator>Alec Grey</dc:creator>
      <pubDate>Sun, 18 Oct 2020 22:54:15 +0000</pubDate>
      <link>https://dev.to/alecgrey/reduce-a-versatile-array-method-45eg</link>
      <guid>https://dev.to/alecgrey/reduce-a-versatile-array-method-45eg</guid>
      <description>&lt;p&gt;&lt;strong&gt;.reduce&lt;/strong&gt; is a confusing enumerable.  But I'd like to think that what makes it confusing can also make it a powerful tool.&lt;/p&gt;

&lt;p&gt;Today I'd like to dispel some of the confusion, and also show some examples of &lt;em&gt;versatile&lt;/em&gt; of a method it is. &lt;/p&gt;

&lt;h2&gt;
  
  
  What does .reduce do?
&lt;/h2&gt;

&lt;p&gt;Let's start with an easy example: Let's say we have an array of numbers that we want to &lt;em&gt;reduce&lt;/em&gt; down to a single value, it's sum. (Let's also say a powerful, Ruby-based wizard took away our &lt;strong&gt;.sum&lt;/strong&gt; method)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK. Let's unpack what the code just did, above.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;.reduce&lt;/strong&gt; as an &lt;em&gt;accumulator&lt;/em&gt; method
&lt;/h3&gt;

&lt;p&gt;Above, we gave &lt;strong&gt;.reduce&lt;/strong&gt; a single parameter (&lt;code&gt;reduce(0)&lt;/code&gt;), as well as named two variables within the pipes (&lt;code&gt;|sum, i|&lt;/code&gt;). Let's call the parameter the &lt;strong&gt;start&lt;/strong&gt; value, and the two variables the &lt;strong&gt;memo&lt;/strong&gt;, and &lt;strong&gt;current_element&lt;/strong&gt;, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_element&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;current_element&lt;/strong&gt; is fairly straightforward; it is the current value of the array you are iterating over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;memo&lt;/strong&gt; stores the return value of the previous iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;start&lt;/strong&gt; provides an optional starting-point, by passing it's value as the first value of &lt;strong&gt;memo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at the above example again, but this time at &lt;em&gt;each iteration&lt;/em&gt; that is happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 1st: 0 + 1 #=&amp;gt; 1&lt;/span&gt;
&lt;span class="c1"&gt;# 2nd: 1 + 1 #=&amp;gt; 2&lt;/span&gt;
&lt;span class="c1"&gt;# 3rd: 2 + 1 #=&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each iteration is adding the &lt;strong&gt;sum&lt;/strong&gt; value to the &lt;strong&gt;current_element&lt;/strong&gt;, then saving that return as the next value for &lt;strong&gt;sum&lt;/strong&gt;.  At the end of the iteration, the final value of &lt;strong&gt;sum&lt;/strong&gt; is returned!&lt;/p&gt;

&lt;p&gt;Before we move on... remember how I said that the parameter value was optional?  If we don't pass in the &lt;strong&gt;start&lt;/strong&gt; value, the method will take &lt;code&gt;array[0]&lt;/code&gt; for the first value of &lt;strong&gt;memo&lt;/strong&gt;, and start iterating with &lt;code&gt;array[1]&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we understand the basics, let's get into some of the fun &lt;em&gt;versatility&lt;/em&gt; that &lt;strong&gt;.reduce&lt;/strong&gt; has to offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using conditional logic to control our returns
&lt;/h2&gt;

&lt;p&gt;Well, I guess I forgot my repellent.  The pesky wizard came back and this time he took our &lt;em&gt;max_by&lt;/em&gt; method...  How am I supposed to find the largest name out of this group of names?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Gandalf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Saruman"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Radagast"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well let's see what &lt;strong&gt;.reduce&lt;/strong&gt; can do!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;longest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;longest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
        &lt;span class="n"&gt;current&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;longest&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 'Radagast'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By implementing some control-flow, we can look at each value of the &lt;code&gt;names&lt;/code&gt; array, and either return the &lt;code&gt;current&lt;/code&gt; if it's longer than the &lt;code&gt;longest&lt;/code&gt;, or keep the same value of &lt;code&gt;longest&lt;/code&gt;for the next iteration.&lt;/p&gt;

&lt;p&gt;This could be written more elegantly as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;longest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;longest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;longest&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 'Radagast'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ternary operators make up some of the bread-and-butter of &lt;strong&gt;.reduce&lt;/strong&gt; control flow.&lt;/p&gt;

&lt;p&gt;There is a glaring flaw in our method, however.  What happens when two or more names are of the same length?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bronson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Dave"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Swanson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Steve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Johnson"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our current &lt;strong&gt;.reduce&lt;/strong&gt; method will only return the &lt;em&gt;first&lt;/em&gt; longest name, since no subsequent values will pass &lt;code&gt;true&lt;/code&gt; for &lt;code&gt;current.length &amp;gt; longest.length&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Returning multiple values with &lt;strong&gt;.reduce&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Remember how we can pass an optional &lt;strong&gt;start&lt;/strong&gt; parameter to our method?  Well we can actually use this to our advantage to create a &lt;strong&gt;.reduce&lt;/strong&gt; method that returns an array of multiple responses!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Bronson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Dave"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Swanson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Steve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Johnson"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;long_names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;long_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;long_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
        &lt;span class="n"&gt;long_names&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;long_names&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; ["Bronson", "Swanson", "Johnson"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To break this down, we need to keep the output consistent across each iteration, so since we want an array of strings, we put an array with an empty string as the &lt;strong&gt;start&lt;/strong&gt; value.  After each iteration, we can either start a new array if &lt;code&gt;current&lt;/code&gt; is greater than the previous longest name, we can add to the array if &lt;code&gt;current&lt;/code&gt; is the same length as the previous longest name, or we can move on, by returning the &lt;code&gt;long_names&lt;/code&gt; array in it's current form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.reduce&lt;/strong&gt; is a powerful tool, so I hope this helped make it more clear how it works.  There's still power yet to be explored with this enumerable, so as a cliffhanger, I'll leave you with another way to refactor the &lt;em&gt;sum&lt;/em&gt; example from earlier:&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;array.reduce {|sum, i| sum + i}&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;Why not try &lt;code&gt;array.reduce(:+)&lt;/code&gt;?&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
