<?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: Max</title>
    <description>The latest articles on DEV Community by Max (@maxinamillion).</description>
    <link>https://dev.to/maxinamillion</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%2F830667%2F5d70f4f4-91f4-4dec-a13a-40a086e2c203.png</url>
      <title>DEV Community: Max</title>
      <link>https://dev.to/maxinamillion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maxinamillion"/>
    <language>en</language>
    <item>
      <title>ActionCable and React for Beginners</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Sun, 30 Apr 2023 23:40:18 +0000</pubDate>
      <link>https://dev.to/maxinamillion/actioncable-and-react-for-beginners-4gm8</link>
      <guid>https://dev.to/maxinamillion/actioncable-and-react-for-beginners-4gm8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Everyone is familiar with HTTP, whether they know it or not. As web developers, we understand that it is an internet protocol used to send and receive requests from a client to a server. A typical exchange looks something like this :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--osYGijzj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnt2hs2b77ms0u2x81hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--osYGijzj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnt2hs2b77ms0u2x81hq.png" alt="Image description" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But sometimes, we want real-time interaction with others. For example, users on Discord or Slack don't manually refresh their applications to get new messages, they are simply received. To facilitate this need for real-time updates, we can use WebSockets.&lt;/p&gt;

&lt;p&gt;Put simply, WebSocket is an alternative internet protocol that allows for dynamic two-way communication between a client and server. Instead of a user requesting new information (like refreshing a page to load new posts), the user will receive data as it is broadcasted.&lt;/p&gt;

&lt;p&gt;In this post, I will be walking you through how to set up a basic Chatroom using Rails ActionCable and a React Frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;First we'll run through the basic application configuration.&lt;/p&gt;

&lt;p&gt;Create a new Rails API in a directory.&lt;br&gt;
&lt;code&gt;rails new  chat_app --api&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the newly created directory and create your React Client&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="c1"&gt;#/chat_app&lt;/span&gt;
&lt;span class="n"&gt;npx&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install @rails/actioncable to your React client&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="c1"&gt;#/chat_app &lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="vi"&gt;@rails&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;actioncable&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Gemfile, uncomment "rack-cors"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ceQ4Vm1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ripubmggg5hxzjld26rm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ceQ4Vm1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ripubmggg5hxzjld26rm.png" alt="Image description" width="800" height="861"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post won't go into deployment, but if you plan on doing so, uncomment "redis" and add the "pg" PostgreSQL gems and change your database adapters as required. This example won't go into deployment so you can leave the "sqlite3" gem and the default settings.&lt;/p&gt;

&lt;p&gt;Uncomment this middleware and change origins to "*" for development purposes. Note you would have to change the origin to your application domain if you were deploying. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8n3zMWqG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54y0v05p5s02ol3mhck6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8n3zMWqG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54y0v05p5s02ol3mhck6.png" alt="Image description" width="800" height="694"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, install your gems and client dependencies.&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="c1"&gt;#/chat_app&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rails
&lt;/h2&gt;

&lt;p&gt;To setup a WebSocket connection, we need to configure both our front and backend to create a 'handshake' or connection. We'll start with establishing the backend.&lt;/p&gt;

&lt;p&gt;In Rails, let's generate a scaffold for a Message model. We'll keep things simple and only have a content attribute for our model.&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;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;scaffold&lt;/span&gt; &lt;span class="no"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
&lt;span class="c1"&gt;#Don't forget to migrate&lt;/span&gt;
&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="ss"&gt;:migrate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving to &lt;code&gt;/app/config/routes.rb&lt;/code&gt;, we can see that Rails has generated resources for our messages already. But we will also need to declare the endpoint for our ActionCable WebSocket server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rta07QZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqnb4ab02vuev7va1igv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rta07QZK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqnb4ab02vuev7va1igv.png" alt="Image description" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a model, it's controller and a server endpoint 'localhost:3000/cable'. Next we need something manage our connections and requests: a Channel.&lt;/p&gt;

&lt;p&gt;Like the controller in MVC, a channel acts as a unit that takes requests and processes those request with respect to the defined actions it receives.&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;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="no"&gt;Chat&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CvSxX9fm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v229e9ct47jy1ftf8eqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CvSxX9fm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v229e9ct47jy1ftf8eqn.png" alt="Image description" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;app/channels/chat_channel.rb&lt;/code&gt;, you will see our ChatChannel with two default actions: subscribed and unsubscribed. When a user attempts to make a WebSocket connection with our server, it will state what kind of request it is and to what channel. We could do different things to process a request such as adding authentication tokens, but we'll focus on the main function of the channel: streaming. &lt;/p&gt;

&lt;p&gt;You can declare a stream from either a specific string, a dynamic interpolated string, or even from an instance of a model. In all cases, the user requests a subscription the ChatChannel and the ChatChannel will in return establish a connection and stream from the specified source.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RLHla3LL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpck0f3i0v4eg7mkc88z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RLHla3LL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpck0f3i0v4eg7mkc88z.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project will proceed using the &lt;code&gt;stream_from "chat"&lt;/code&gt; configuration so we'll comment out the other examples.&lt;/p&gt;

&lt;p&gt;Now that we've established a way for users to connect to our WebSocket server, we need to define when our server actually broadcasts information to our users.&lt;/p&gt;

&lt;p&gt;In general, we're going to want to broadcast data to our channel when users create new messages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AlH5b9sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/et2gmmf8a176ru3led9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AlH5b9sA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/et2gmmf8a176ru3led9j.png" alt="Image description" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActionCable.server.broadcast("chat", @message)&lt;/code&gt; tells our server to broadcast our &lt;code&gt;@message&lt;/code&gt; to the stream "chat". If you broadcast from a model, you will need to use different syntax, refer to &lt;a href="https://guides.rubyonrails.org/action_cable_overview.html"&gt;https://guides.rubyonrails.org/action_cable_overview.html&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  React
&lt;/h2&gt;

&lt;p&gt;For brevity, I will only cover setting up WebSockets on the frontend.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;/app/client/src&lt;/code&gt; create a new file &lt;code&gt;cable.js&lt;/code&gt;. This will manage the creation of our client-side 'consumer'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_B2DKbY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cor0s2duakn39fp20rp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_B2DKbY9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cor0s2duakn39fp20rp.png" alt="Image description" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the protocol of our &lt;code&gt;URL&lt;/code&gt; is now 'ws' not 'http'. This will tell our server that the user is attempting to establish a WebSocket. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;App.js&lt;/code&gt;, we want the client to make a subscription request to our ChatChannel. Thanks to &lt;code&gt;@rails/actioncable&lt;/code&gt; we can also describe what we want to happen when we are connected, and when we receive data (if our connection is established).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UCZiO1QR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uineqcige0ws6juukm72.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UCZiO1QR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uineqcige0ws6juukm72.png" alt="Image description" width="800" height="1296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From our backend we can see if a request is successful by viewing our terminal. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y1AQ3eBR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4brma948bsmxc5mfi6y3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y1AQ3eBR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4brma948bsmxc5mfi6y3.png" alt="Image description" width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we make a post request to our backend, our Messages Controller broadcasts our message to the "chat" stream. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--odCbB1Nz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u88hdl1zxjkxrcj0su85.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--odCbB1Nz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u88hdl1zxjkxrcj0su85.png" alt="Image description" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When it broadcasts, our clients are set up to &lt;code&gt;setMessages&lt;/code&gt; using that received information. &lt;/p&gt;

&lt;p&gt;You can view realtime updates by opening the application an in incognito window. You will notice that both will update whenever the other sends a message.&lt;/p&gt;

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

&lt;p&gt;WebSocket is a great tool to allow for interactive communication for users. It was difficult for me at first to really get a grasp on some of the examples out there, so I hope this provides a very basic illustration of how to set up ActionCable with a React Frontend application. I didn't cover management of connection requests or illustrate the use of multiple streams, but I think this shows the very basics on how to get a chatroom going. Let me know if there's anything I missed or anything you'd want me to cover! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>rails</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Basics of Active Record Validations</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Sat, 08 Apr 2023 18:56:14 +0000</pubDate>
      <link>https://dev.to/maxinamillion/basics-of-active-record-validations-3g1</link>
      <guid>https://dev.to/maxinamillion/basics-of-active-record-validations-3g1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Ruby on Rails ('Rails') is a web app development framework that provides a foundation for developers to build on. Rails provides tools that make common development tasks easier. For instance: managing a database. Rails provides Active Record to facilitate the management of data; it acts as the model in MVC&lt;sup&gt;1&lt;/sup&gt;. Active Record is an &lt;a href="https://dev.to/albam476/what-is-object-relational-mapping-orm-kgi"&gt;ORM&lt;/a&gt; (Object Relational Mapper) that simplifies database creation, data associations, and data validations. Data validations protect our application from user error and malicious attempts at manipulation. Before explaining validations themselves, we'll cover the difference between invalid and valid data. If you want to jump straight into validations, click here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invalid vs Valid Data
&lt;/h2&gt;

&lt;p&gt;Our applications do not exist in a vacuum. We will ideally have real people using and interacting with our programs constantly. In a perfect world, everyone would know our intentions as developers when asking for user input in things like a username, email, phone number, etc. However, our intentions are not always clear, and our users will inevitably make mistakes like forgetting a digit in their phone number or leaving a username field blank. &lt;/p&gt;

&lt;p&gt;Additionally, malicious users may make bad faith attempts to use our program to access otherwise unauthorized data. For example, someone may attempt to gain admin privileges by creating a request to create an account with an 'admin' parameter.&lt;br&gt;
In either case, we could call these examples of 'invalid data' - information that does not match our intentions when asking for user input. &lt;/p&gt;

&lt;p&gt;By contrast, valid data meets the developer's intentions and allows our applications to run smoothly. Knowing this, how can we prevent invalid data from entering our database? Through Active Record, we have Validations.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Validations
&lt;/h1&gt;

&lt;p&gt;Validations are rules for a model that declare whether or not data is valid based on specified criteria. Validations are run on the create, save, and update methods and their bang versions (create!, save!, update!).&lt;/p&gt;

&lt;p&gt;Active Record provides pre-defined 'validation helpers' that provide common rules for validation. &lt;a href="https://guides.rubyonrails.org/active_record_validations.html#inclusion"&gt;There are many validation helpers&lt;/a&gt;, but the names for them are fairly self-explanatory. Generally, the syntax for implementing validations is &lt;code&gt;validates :model_attribute, validation_helper: {helper_options}&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Validation Practice Example
&lt;/h1&gt;

&lt;p&gt;Suppose you work at a school and you are working on creating an application to track students and their classes. In this example, we'll create the model for students.&lt;/p&gt;

&lt;p&gt;You'd want to prevent users from having the same username, and at minimum we would expect a student's profile to have a username and a name. While passwords are also an intuitive necessity, user authentication will be ignored to keep this example focused on data validation.&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;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
&lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uniqueness: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;length: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;minimum: &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inclusion: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;in: &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;16&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;Here in our User model we've added validations so that &lt;code&gt;:username&lt;/code&gt; and &lt;code&gt;:name&lt;/code&gt; are present (the values are neither nil or a blank string), &lt;code&gt;:username&lt;/code&gt; is unique among all other values of &lt;code&gt;:username&lt;/code&gt; for the User model, &lt;code&gt;:username&lt;/code&gt; is at least four characters long, and that the value of &lt;code&gt;:age&lt;/code&gt; is included between the range 10-16.  &lt;/p&gt;

&lt;p&gt;Now if we try to create a User without providing any parameter we will see that &lt;code&gt;User.create()&lt;/code&gt; will be unsuccessful.&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="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;#SQL queries&lt;/span&gt;
&lt;span class="c1"&gt;#&amp;lt;User:0x000055b999d51670 id: nil, username: nil, name: nil, age: nil, created_at: nil, updated_at: nil&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that our program attempted to run the necessary SQL queries for our database, but since our returned object lacks an &lt;code&gt;:id&lt;/code&gt; we can tell it was unsuccessful. Now, only valid parameters will allow for the creation of a model instance and save it to the database.&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="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="ss"&gt;:"upDog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="ss"&gt;:"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;#A series of SQL queries&lt;/span&gt;
   &lt;span class="c1"&gt;#&amp;lt;User:0x0000558262db3410 id: 1, username: "upDog", name: "John", age: 10&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the parameters pass the validations specified in our model, the object was properly saved and now has an id.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handling
&lt;/h2&gt;

&lt;p&gt;Validations also provide error messages upon failure if you use the bang versions of our method calls. Error handling is useful as we may want to alert our users to why their attempts are unsuccessful.&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="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;#`raise_validation_error': Validation failed: Username can't be blank, Name can't be blank, Username is too short (minimum is 4 characters), Age is not included in the list (ActiveRecord::RecordInvalid)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the bang versions of create, update, and save, a special Exception Object will be raised which will detail why validations failed. We can then return this information to our Controller and render the messages to our prospective new user. &lt;/p&gt;

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

&lt;p&gt;Rails provides many tools that simplify common tasks so that you can focus on the more complex and fun parts of your application. With Active Record, we can ensure only valid data is kept in our database through the use of validations. Validations check if parameters passed to the &lt;code&gt;create&lt;/code&gt; , &lt;code&gt;update&lt;/code&gt; , and &lt;code&gt;save&lt;/code&gt; methods meet criteria specified in our Model. If the parameters don't pass our validations, we can send error messages to our user and inform them of needed corrections.&lt;/p&gt;

&lt;p&gt;1 &lt;a&gt;&lt;/a&gt;&lt;a&gt;&lt;/a&gt;: MVC, Model-View-Controller, is an architectural design pattern often used in web development&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>ruby</category>
      <category>activerecord</category>
    </item>
    <item>
      <title>What is Object-Relational Mapping (ORM)?</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Sun, 26 Feb 2023 20:01:32 +0000</pubDate>
      <link>https://dev.to/maxinamillion/what-is-object-relational-mapping-orm-kgi</link>
      <guid>https://dev.to/maxinamillion/what-is-object-relational-mapping-orm-kgi</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As programmers, we are always tasked with representing real life information as code in our programs. To navigate this challenge, we often use different frameworks or design choices to represent more abstract data. For example, a company may want to track information about their employees. We cannot represent everything about each employee but we can define specific, meaningful aspects of interest like an employee's name, address, salary, department, etc. &lt;/p&gt;

&lt;p&gt;One method of framing data is Object-Relational Mapping (ORM). Put simply, ORM is a design pattern to follow when using an object-oriented language with a database. Following ORM conventions, you can keep your code better organized and DRY.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organization
&lt;/h2&gt;

&lt;p&gt;An application may have to access hundreds of thousands of instances within a database. While individual programmers could devise their own ways to communicate with the same database, follwing ORM conventions provides structure to this communication. Following convetions will make code easier for both you and others to understand.&lt;/p&gt;

&lt;p&gt;To understand ORM, we should first review object-oriented languages. Object-oriented langauges can use classes to represent a general category of a thing, like cars, cats, or employees.&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="c1"&gt;#code will be written in Ruby&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Employee&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
    &lt;span class="vi"&gt;@address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;
    &lt;span class="vi"&gt;@salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;
    &lt;span class="vc"&gt;@@all&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each class can have instances, unique indivduals within the class; a Toyota Corolla, a Tabby, or John Smith. Instances can have different vaues among each other, but are ultimately categorized under their shared class.&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;employee1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Employee&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="s2"&gt;"John Smith"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"1684 Ravine Place Los Angeles, CA"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;employee1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; Employee&lt;/span&gt;

&lt;span class="n"&gt;employee2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Employee&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="s2"&gt;"Jane Doe"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"1909 Tower Rd Derry, ME"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;43000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;employee2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; Employee&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Knowing this, we can now organize our code by 'mapping' it onto a database following ORM conventions. We will create a table for every class in our program with a row to represent each instance of the class. For our Employee class, we will have an employees table and two rows for our two employees. Note that while our class name is singular, the name of our table is plural.&lt;/p&gt;

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

&lt;p&gt;ORM also allows us to keep our code DRY. Going back to our previous example of an employee listing, our program will need to have some sort of connection to the database itself. For this example, SQLite3 will be used.&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;database_connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SQLite3&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Database&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="s1"&gt;'db/company.db'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will have to make a table to store our employee information. The table is created by passing SQL as an argument of of the &lt;code&gt;execute&lt;/code&gt; method. We will ask our program to create a table named employees, if it does not already exist. We will also name each column, with their data type, for our employees table which will store the different values within our &lt;code&gt;Employee&lt;/code&gt; class.&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;database_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CREATE TABLE IF NOT EXISTS employees( id INTEGER PRIMARY KEY, name TEXT, address TEXT, salary INTEGER)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our table has been created, so next we will use attributes of our instances to fill the rows and respective columns within our database table. Note that we are not directly saving the object itself into the table, but rather accessing attributes within the instances and placing them in the appropriate columns of our table. Any modifications to the record or instance itself will not automatically change the other.&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;database_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"INSERT INTO employees (name, address, salary, VALUES ("&lt;/span&gt;&lt;span class="no"&gt;John&lt;/span&gt; &lt;span class="no"&gt;Smith&lt;/span&gt;&lt;span class="s2"&gt;" , "&lt;/span&gt;&lt;span class="mi"&gt;1684&lt;/span&gt; &lt;span class="no"&gt;Ravine&lt;/span&gt; &lt;span class="no"&gt;Place&lt;/span&gt; &lt;span class="no"&gt;Los&lt;/span&gt; &lt;span class="no"&gt;Angeles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CA&lt;/span&gt;&lt;span class="s2"&gt;" , 30000)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;database_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"INSERT INTO employees (name, address, salary, VALUES ("&lt;/span&gt;&lt;span class="no"&gt;Jane&lt;/span&gt; &lt;span class="no"&gt;Doe&lt;/span&gt;&lt;span class="s2"&gt;" , "&lt;/span&gt;&lt;span class="mi"&gt;1909&lt;/span&gt; &lt;span class="no"&gt;Tower&lt;/span&gt; &lt;span class="no"&gt;Rd&lt;/span&gt; &lt;span class="no"&gt;Derry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ME&lt;/span&gt;&lt;span class="s2"&gt;" , 43000)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, as you can see, manually inserting each instance is repetitive and will grow exponentially more difficult and tedious to support the more employees we add. So instead, we can create an instance method for our class which we can reuse.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Employee&lt;/span&gt;
&lt;span class="o"&gt;~~~~&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database_connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;database_connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"INSERT INTO employees (name, address, salary) VALUES (?, ?, ?)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;age&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;Our &lt;code&gt;#save&lt;/code&gt; method will take a database_connection as a parameter and insert our instance's values into the appropriate columns of the database we provide. Now we can simply call our &lt;code&gt;save&lt;/code&gt; instance method on each employee instance and pass our database connection as its argument.&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;database_connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SQLite3&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Database&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="s1"&gt;'db/company.db'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&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;employee&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database_connection&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;Even as our application grows, we will no longer have to write separate lines of code to save our classes into our database. &lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;While there are multiple libraries across different programming langauges that help map objects onto databases. These libraries are simply following specific conventions which help simplify your code as long as you abide by their schema. In short, Object-Relational Mapping (ORM) is a design pattern that can be used when working with an object-oriented language and a database. While there may be different approaches, ORM follows the conventions of mapping Classes to Tables and rows to instances. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>objectrelationalmapping</category>
      <category>orm</category>
    </item>
    <item>
      <title>React Controlled Forms</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Mon, 17 Oct 2022 23:31:03 +0000</pubDate>
      <link>https://dev.to/maxinamillion/react-controlled-forms-2n0l</link>
      <guid>https://dev.to/maxinamillion/react-controlled-forms-2n0l</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;Nearly all web applications use forms. Everything from logging into social media, making new posts, and customizing your profile uses forms. React provides a useful tool that allows us to create controlled forms: forms whose component state (what the internal code tracks) matches the user interface state (what the user sees in the application).&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Review
&lt;/h3&gt;

&lt;p&gt;In React, &lt;strong&gt;state&lt;/strong&gt; is data that is dynamic. It changes over time as users interact with the application. And it is used in controlled forms to give the values for each input.&lt;/p&gt;

&lt;p&gt;To create controlled forms you should first be familiar with React Hooks, specifically the State Hook. React Hooks are special predefined functions within the React library. The State Hook, 'useState', allows developers to access/'hook into' React's internal state of our components. &lt;/p&gt;

&lt;h4&gt;
  
  
  useState
&lt;/h4&gt;

&lt;p&gt;To use the State Hook, we first need to import it from the React library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;stateVar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStateVar&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;return&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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;stateVar&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&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once imported, we can use the State Hook by invoking the useState function. This function returns an array of two elements: a state variable and a setter function. When invoking useState, you can declare the state variable's initial value, in this case an empty string.&lt;/p&gt;

&lt;p&gt;To update a state variable, you must invoke the setter function. After a setter function is invoked, the state is set asynchronously and upon completion, the component is rerendered. If we were to call &lt;code&gt;setStateVar("Hello World")&lt;/code&gt; our program will begin to asynchronously set the state variable to &lt;code&gt;"Hello World"&lt;/code&gt; and upon rerender our &lt;code&gt;h1&lt;/code&gt; will read &lt;code&gt;Hello world&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Although there is more to the State Hook, we can move onto how they are used to create controlled forms.&lt;/p&gt;

&lt;h1&gt;
  
  
  Controlled Forms
&lt;/h1&gt;

&lt;p&gt;Controlled forms are forms that derive the values for its inputs from state. Let's look at a simple example of a controlled form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFirstName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLastName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Henry&lt;/span&gt;&lt;span class="dl"&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;form&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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;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="s2"&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="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="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;The above example is a controlled form because the values for the input fields are defined by their respective state variables. But our program as it is would not allow a user to change the values of these inputs. So how do we allow for users to actually fill out the form and change the state of our application?&lt;/p&gt;

&lt;p&gt;Input fields can listen for many different event types; for this instance we will use &lt;code&gt;onChange&lt;/code&gt;. &lt;code&gt;onChange&lt;/code&gt; will trigger every time the value of the input changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&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="s2"&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;handleFirstNameChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;Now everytime the user alters the input element, it will call the function &lt;code&gt;handleFirstNameChange&lt;/code&gt; and pass the event object as an argument of the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleFirstNameChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setFirstName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this event argument, we can access the value currently entered in our input element: &lt;code&gt;event.target.value&lt;/code&gt; and use our setter function to update our state variable. Adding a similar function for our &lt;code&gt;lastName&lt;/code&gt; input and state variable would allow the user to interact with the form while changing state within the component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abstractions
&lt;/h3&gt;

&lt;p&gt;In our previous example, we only had two state variables. But in a world where forms often ask for passwords, addresses, emails, phone numbers, etc., creating unique state variables and invoking unique callback functions for each, while doable, can easily become repetitve. It may be preferable to have a single state object variable.&lt;/p&gt;

&lt;p&gt;For simplicity we will build off our previous example with only the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; state variables. But we will consolidate them into one object variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//const [firstName, setFirstName] = useState("John");&lt;/span&gt;
  &lt;span class="c1"&gt;//const [lastName, setLastName] = useState("Henry");&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;userObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUserObj&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; 
                                            &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Henry&lt;/span&gt;&lt;span class="dl"&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;form&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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;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="s2"&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="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="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;Here you can see we replaced our two state variables with one by creating the &lt;code&gt;nameObj&lt;/code&gt; state variable with the default value of an object with keys &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Making these input fields dynamic requires a bit more complexity than using individual callback &lt;code&gt;handleChange&lt;/code&gt; functions, but it is very useful and easy once you get used to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&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;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lastName&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;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;Like in our previous build, we have an onChange event listener that takes a callback handler. But this time we have added an id prop which will be used in our event handler to determine which field is being updated.&lt;/p&gt;

&lt;p&gt;Unlike our previous build, we cannot simply call the event handler and directly set the state variable to the value of the current state. Since the same event handler is being used on two different inputs, we need a way to differentiate each input to know which value we intend to update. Additionally, we need to be careful not to simply use &lt;code&gt;setUserObj(event.target.value)&lt;/code&gt; as this would mean the whole state variable would become a single value, no longer having both a first and last name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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;id&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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="c1"&gt;//setFirstName(event.target.value);&lt;/span&gt;
    &lt;span class="nx"&gt;setUserObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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;In the event handler, we can grab the target element's id and set it as our key since they match the keys of our &lt;code&gt;userObj&lt;/code&gt;. Likewise we can save our target element's value to a variable as well. Finally, we invoke our setter function &lt;code&gt;setUserObj&lt;/code&gt; with argument &lt;code&gt;{...userObj , [key]: value }&lt;/code&gt;. We use the spread operator to copy our current state of the userObj and use our &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; pair to update our desired object property. Doing so will update only our intended object while leaving all others in their current state. &lt;/p&gt;

&lt;p&gt;Creating one state variable object can help organize your code and make it easier to add and track additional fields to your form.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Use Controlled forms?
&lt;/h1&gt;

&lt;p&gt;Now you know how to create controlled forms, but why use them? One common use is for data validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation
&lt;/h3&gt;

&lt;p&gt;Users often make mistakes while filling out forms. But controlled forms allow us to catch these mistakes and alert the user so as to allow the application to be used as intended. In our previous example, we had inputs where we intended to capture a user's first and last name. But suppose a user inputted a number for their first name. Our code as it was would allow that input and we could end up with a user who's name appears as "34Mmy 5m1th". As l33t as that is, we may not want to allow users to do this.&lt;/p&gt;

&lt;p&gt;Controlled forms can validate the data a user enters before actually setting state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUserObj&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; 
                                            &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Henry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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;id&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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="nx"&gt;setUserObj&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Input is not valid&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;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;form&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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&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;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;input&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lastName&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;handleUserChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userObj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;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="s2"&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="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="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;Within our &lt;code&gt;handleUserChange&lt;/code&gt; function, we added an &lt;code&gt;if else&lt;/code&gt; statement to validate our target's input. In this case, we allow our &lt;code&gt;userObj&lt;/code&gt; to update if the input's value is an empty string or not a number. Otherwise, we print out an error to our console. You could write an alternative else statement to allow for some notification to the user, but for this simple example we will leave it with a simple &lt;code&gt;console.log&lt;/code&gt; for the dev.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>controlledforms</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Array Iteration for Beginners</title>
      <dc:creator>Max</dc:creator>
      <pubDate>Wed, 29 Jun 2022 00:54:40 +0000</pubDate>
      <link>https://dev.to/maxinamillion/array-iteration-for-beginners-2i46</link>
      <guid>https://dev.to/maxinamillion/array-iteration-for-beginners-2i46</guid>
      <description>&lt;h1&gt;
  
  
  A Brief Review
&lt;/h1&gt;

&lt;p&gt;Just about anything and everything can be represented by data. Some things are represented fairly easily on their own; for instance, the red color of an apple, my cat's age being 1 year old, or a character's catchphrase. In code, these can be represented by standalone variables: &lt;br&gt;
&lt;code&gt;let appleColor = 'red'&lt;br&gt;
let mochiAge = 1&lt;br&gt;
let buzzCatchphrase = 'To Infinity and Beyond'&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Some data is best represented in pairs of keys and values. In this case, data is organized in what can be thought of as a dicitonary, where you look up the key or word and find the value or definition. This type of data structure in JavaScript is called an object. For a concrete example, we could store information about an employee in an object as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let employee: {name: "John Smith", age: 32, title: "Office Manager"}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Data can also be represented as a list. Doing so may indicate a sort of relationship between variables or otherwise organize them as a collective. For example, the winning numbers of a lottery or a person's favorite movies. For these examples and many more, we use arrays. Arrays are a type of data structure; a way of associating and organizing information. The previous two examples can be represented as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let winningNumbers = [02, 27, 42, 44, 51, 25]&lt;br&gt;
let favoriteMovies = ['The Dark Knight Rises', 'Spirited Away', 'Stardust']&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When using arrays, we often have to look through the array and interact with the items within it in a process called array iteration. &lt;/p&gt;

&lt;h1&gt;
  
  
  Array Iteration
&lt;/h1&gt;

&lt;h2&gt;
  
  
  .filter()
&lt;/h2&gt;

&lt;p&gt;The filter method, as the name implies, will iterate through an array and remove, or filter, elements that do not meet a specified criteria. A simple example would be going through a list of numbers, and only keeping the numbers greater than 3 (filtering out numbers less than 3). Elements that meet the criteria will be returned in the form of an array.&lt;/p&gt;

&lt;p&gt;The filter method takes a function as its argument (a callback function) and use it to determine what elements should be returned. This callback function is fed each element of the original array into it, and will return only the elements that meet the intended criteria. &lt;/p&gt;

&lt;p&gt;The previous example could look something like this:&lt;br&gt;
&lt;code&gt;let list = [1,2,3,4,5]&lt;/code&gt;&lt;br&gt;
&lt;code&gt;function greaterThanThree(num){&lt;br&gt;
return num &amp;gt; 3&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;code&gt;list.filter(greaterThanThree(num)) // =&amp;gt; [4,5]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now let's look at a more complex example of .filter(). Suppose you had a watchlist app, similar to IMDB, where you have a list of movies and details about them including things like genre, leading actor, budget, etc. This data could be represented in an array of objects as follows: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;let movies = &lt;br&gt;
[{title: 'The Dark Knight', genre: 'superhero', star: 'Christian Bale'}, &lt;br&gt;
{title:'Captain America', genre: 'superhero', star: 'Chris Evans'}, &lt;br&gt;
{title: 'Snow Piercer', genre:'action', star: 'Chris Evans'}, &lt;br&gt;
{title: 'John Wick', genre: 'action', star: 'Keanu Reeves'}]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we wanted to create a new array from this one to include only superhero movies, we would first create a function to be used as a callback in the .filter() method to check and return any movie in the superhero genre.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function superHeroes(movie){&lt;br&gt;
return movie['genre'] === 'superhero'&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next we would invoke .filter() onto the movies array, passing the superHeroes function as an argument.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;movies.filter(superHeroes)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Doing so will feed each individual element in the movies array into the superheroes function and then return a true or false based on the movie's genre. If the function returns true, it is added to an array that will be returned by the filter method. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;movies.filter(superHeroes) // =&amp;gt;[{title: 'The Dark Knight', genre: 'superhero', star: 'Christian Bale'}, &lt;br&gt;
{title:'Captain America', genre: 'superhero', star: 'Chris Evans'}]&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  .map()
&lt;/h2&gt;

&lt;p&gt;What if we wanted to modify every element in an array? For a simple example, suppose we had a list of numbers and we wanted to have a list of all those numbers doubled. In this case, we would use the .map() method. This method takes a callback function as an argument, and will create a new array that contains the original array elements modified by the callback funciton. &lt;/p&gt;

&lt;p&gt;The above example could look something like this:&lt;br&gt;
&lt;code&gt;let numbers = [1,2,3,4]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function doubleNumbers (number){&lt;br&gt;
return number * 2&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numbers.map(doubleNumbers) // =&amp;gt; [2,4,6,8]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you can see, each number in the numbers array was passed to the doubleNumbers function as an argument, and then was returned as the value of itself times 2. These returned values were stored in a new array, and did not modify the original numbers array. &lt;/p&gt;

&lt;p&gt;Just like with the filter method, lets explore a more complex example. Suppose you had an array of objects consisting of iconic characters and a phrase. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;let characters = [{name: 'Woody', phrase: "You're my favorite deputy!"}, {name: 'Buzz', phrase: 'To infinity and beyond!'}, {name: 'Courage', phrase: 'The things I do for love.'}]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But instead of their catchphrases, you wanted to have the phrase be an introduction instead. First we need to write a function that will modify a character element and return the modified element.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function introduction(character){&lt;br&gt;
character['phrase'] =&lt;/code&gt;Hi, my name is ${character['name']}.&lt;code&gt;&lt;br&gt;
return character&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next we invoke the .map() iterator on the characters array, and pass it our introduction callback function, and it should return an array with the modified phrases.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;character.map(introduction) // =&amp;gt;[{name: 'Woody', phrase: 'Hi, my name is Woody.'}, {name: 'Buzz', phrase: 'Hi, my name is Buzz.'},{name: 'Courage', phrase: 'Hi, my name is Courage.'}]&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;There are more iterator methods for arrays than the two covered in this post. And each one provides a different way to interact with the elements in the array to achieve a goal. Hopefully with these two examples, you have gained a basic understanding of array iteration, callback functions, and how imporant of tools these concepts are for any coding project.&lt;/p&gt;

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