<?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>Forem: jgifford82</title>
    <description>The latest articles on Forem by jgifford82 (@jgifford82).</description>
    <link>https://forem.com/jgifford82</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%2F863514%2F5db83ce1-5752-4b07-b1dd-2e92bb64c247.JPG</url>
      <title>Forem: jgifford82</title>
      <link>https://forem.com/jgifford82</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jgifford82"/>
    <language>en</language>
    <item>
      <title>Infinite Scroll</title>
      <dc:creator>jgifford82</dc:creator>
      <pubDate>Thu, 01 Jun 2023 01:53:23 +0000</pubDate>
      <link>https://forem.com/jgifford82/infinite-scroll-1gg3</link>
      <guid>https://forem.com/jgifford82/infinite-scroll-1gg3</guid>
      <description>&lt;p&gt;I'm at the end of the fifth (and final!) phase of my coding boot camp. We previously learned about JavaScript, React, and Ruby on Rails. In this phase, we had to complete a full stack project utilizing React and Ruby on Rails that also implements something new that we hadn't learned in the boot camp. I chose to implement infinite scroll.&lt;/p&gt;

&lt;p&gt;In my project, infinite scroll pulls in additional data as a user scrolls down the page. This can be a helpful alternative to fetching all the data up front when there is a large amount of data, which could potentially be slow to load.&lt;/p&gt;

&lt;p&gt;It's possible to implement infinite scroll using React's built-in functions, though I chose to implement it using the &lt;a href="https://www.npmjs.com/package/react-infinite-scroll-component" rel="noopener noreferrer"&gt;react-infinite-scroll-component&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Here's how I did it:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Set up the backend controller
&lt;/h2&gt;

&lt;p&gt;Note: As I build out projects, I like to set up each feature on the backend first, then the frontend, though you don't necessarily have to do it in this order. &lt;/p&gt;

&lt;p&gt;My project is a tea recipe sharing app, and I wanted infinite scroll to pull in 3 teas at a time. Since it's pulling in multiple teas, it's going to route to the index method of the teas controller. Therefore, my routes.rb file needs the routing logic to have the teas resource with index method:&lt;br&gt;
&lt;code&gt;resources :teas, only: [:index]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the teas controller, I set up the index method to GET 3 teas at a time alphabetically by name regardless of capitalization. The data is broken up into pages containing a specific number of items, 3 teas per page in this example, reducing the amount of data transferred and improving the overall performance. The page number parameter from the request is converted to an integer, and checks if the integer is positive. Otherwise, it defaults to 1 to prevent the database error "OFFSET must not be negative."&lt;/p&gt;

&lt;p&gt;The line &lt;code&gt;offset((page - 1) * per_page)&lt;/code&gt; skips the appropriate number of teas based on the current page number and the number of teas per page. Then, &lt;code&gt;limit(per_page)&lt;/code&gt; limits the result to the specified number of teas per page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    def index
        page = params[:page].to_i.positive? ? params[:page].to_i : 1
        per_page = 3

        teas = Tea.order('lower(name)').offset((page - 1) * per_page).limit(per_page)
        render json: teas, include: ['category', 'reviews', 'reviews.user']
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tested this in Postman by sending a GET request to localhost:3000/teas, which successfully returns JSON displaying the first 3 teas in alphabetical order.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Install React infinite scroll component
&lt;/h2&gt;

&lt;p&gt;With the backend taken care of, it's time to switch gears to the frontend. In my project, I navigated to the folder containing my frontend files to install the React infinite scroll component. It's important to install it in the correct folder directory, otherwise it could lead to errors, which I learned the hard way! After navigating to the correct folder, in this case "client," I ran &lt;code&gt;npm i react-infinite-scroll-component&lt;/code&gt; based on the &lt;a href="https://npm.io/package/react-infinite-scroll-component" rel="noopener noreferrer"&gt;component documentation&lt;/a&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%2Fuploads%2Farticles%2Fc0iuqppi4vjyvouspw9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0iuqppi4vjyvouspw9n.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Import InfiniteScroll
&lt;/h2&gt;

&lt;p&gt;The component that will utilize infinite scroll needs to import it. In my project, I used it in my TeasList component, so it has this code at the top:&lt;br&gt;
&lt;code&gt;import InfiniteScroll from "react-infinite-scroll-component";&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Fetch data
&lt;/h2&gt;

&lt;p&gt;When the TeasList component mounts, a useEffect hook fetches teas data as shown below. It's only pulling in the first page of teas since the backend was set up to divide the data into pages. It converts the data to JSON, then populates teas state with that data. I used useContext for teas state to prevent props drilling through multiple components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  useEffect(() =&amp;gt; {
    fetch("/teas?page=1")
      .then((r) =&amp;gt; r.json())
      .then((data) =&amp;gt; setTeas(data));
  }, [setTeas]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the top of the TeasList component, I imported the necessary hooks for that fetch:&lt;br&gt;
&lt;code&gt;import { useContext, useState, useEffect } from "react";&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Teas context is imported as well:&lt;br&gt;
&lt;code&gt;import { TeasContext } from "../context/teas";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inside the function body of the TeasList component, teas state is destructured from TeasContext so it can be used in the fetch request, as well as the next fetch request in the next step:&lt;br&gt;
&lt;code&gt;const { teas, setTeas } = useContext(TeasContext);&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Fetch more data
&lt;/h2&gt;

&lt;p&gt;The previous step only pulls in the first page of data when you first navigate to the page. Another function is needed to pull in more data. The fetchMoreTeas function below handles this. The function is triggered when the user reaches the end of the page. It updates teas state with newly fetched data, increments the page state for the next fetch, and sets hasMore to false if there are no more teas to fetch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const fetchMoreTeas = async () =&amp;gt; {
    const response = await fetch(`/teas?page=${page + 1}`);
    const data = await response.json();
    if (data.length &amp;gt; 0) {
      setTeas((prevTeas) =&amp;gt; [...prevTeas, ...data]);
      setPage((prevPage) =&amp;gt; prevPage + 1);
    } else {
      setHasMore(false); 
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the function updates &lt;code&gt;page&lt;/code&gt; and &lt;code&gt;hasMore&lt;/code&gt; state, both of those are set up within the TeasList component. The &lt;code&gt;page&lt;/code&gt; state keeps track of the current page for fetching teas and is set with page 1 as the default value:&lt;br&gt;
  &lt;code&gt;const [page, setPage] = useState(1);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;hasMore&lt;/code&gt; state keeps track of whether there is more data available for infinite scroll and is set as true by default. &lt;br&gt;
  &lt;code&gt;const [hasMore, setHasMore] = useState(true);&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Render InfiniteScroll component
&lt;/h2&gt;

&lt;p&gt;Now that infinite scroll is imported and fetches are set up, we need to render the infinite scroll functionality. The data being displayed needs to be wrapped within &lt;code&gt;&amp;lt;InfiniteScroll&amp;gt; &amp;lt;/InfiniteScroll&amp;gt;&lt;/code&gt;. In the example below, teas state is being mapped over to display the tea name and blend, and the ul contains the tea id as a key. That code block is wrapped with InfiniteScroll, which contains props that are necessary for infinite scroll to work. You can find these props in the &lt;a href="https://www.npmjs.com/package/react-infinite-scroll-component" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; as well as other props you can use depending on how you want to implement infinite scroll. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;dataLength&lt;/code&gt; prop is the length of the data array. If the length is falsy (0, null, or undefined), the OR operator evaluates to 0, ensuring a valid value so the page doesn't crash. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;next&lt;/code&gt; prop specifies the function that should be called when the user reaches the end of the scrollable content, which is fetchMoreTeas in this case. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;hasMore&lt;/code&gt; prop is a Boolean indicating if there is more data to load; fetchMoreTeas sets it to false when there is no more data. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;loader&lt;/code&gt; prop displays a "Loading..." header while loading more data.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;div&amp;gt;
      &amp;lt;InfiniteScroll
        dataLength={teas.length || 0}
        next={fetchMoreTeas}
        hasMore={hasMore}
        loader={&amp;lt;h4&amp;gt;Loading...&amp;lt;/h4&amp;gt;}
      &amp;gt;
        {teas.map((tea) =&amp;gt; (
          &amp;lt;ul key={tea.id}&amp;gt;
            {tea.name}
            {tea.blend}
          &amp;lt;/ul&amp;gt;
        ))}
      &amp;lt;/InfiniteScroll&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully this helps others implement infinite scroll! Happy scrolling!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>webdev</category>
      <category>rails</category>
    </item>
    <item>
      <title>Request response flow between React frontend &amp; Ruby on Rails backend</title>
      <dc:creator>jgifford82</dc:creator>
      <pubDate>Thu, 30 Mar 2023 22:28:23 +0000</pubDate>
      <link>https://forem.com/jgifford82/request-response-flow-between-react-frontend-ruby-on-rails-backend-7ka</link>
      <guid>https://forem.com/jgifford82/request-response-flow-between-react-frontend-ruby-on-rails-backend-7ka</guid>
      <description>&lt;p&gt;I'm at the end of the fourth phase of my coding boot camp. We previously learned about JavaScript, React, and Ruby. This phase focused on learning Rails, and we had to complete a full stack project utilizing React and Ruby on Rails. One of the concepts from this phase I'd like to dig into is the frontend to backend request response flow. This refers to data shared between a frontend JavaScript application and a backend API application. Rails will basically take an HTTP request and generate a properly-formatted response. I will use an example from my project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Frontend Request&lt;/strong&gt;&lt;br&gt;
The process starts when the user interacts with the frontend and triggers an event, such as clicking a button or submitting a form. For example, the fetch request below is triggered when a user logs in. It sends a request to the endpoint &lt;code&gt;/login&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;An HTTP request is sent to the backend API endpoint. POST is the HTTP verb in this request. The request contains information, such as the user's input, which is their username and password in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function handleSubmit(e) {
    e.preventDefault();
    setIsLoading(true);

    fetch("/login", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(values),
    }).then((r) =&amp;gt; {
      setIsLoading(false);
      if (r.ok) {
        setErrors([]);
        r.json().then((user) =&amp;gt; {
          setUser(user);
          navigate("/books");
        });
      } else {
        r.json().then((err) =&amp;gt; setErrors(err.error));
      }
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Backend Router&lt;/strong&gt;&lt;br&gt;
The backend Ruby on Rails server receives the request and routes it to the corresponding controller and action method contained in the routes.rb file. In the login route below, it's directing a POST request for the &lt;code&gt;/login&lt;/code&gt; endpoint to the sessions controller's create method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;post "/login", to: "sessions#create"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Backend Controller&lt;/strong&gt;&lt;br&gt;
The controller communicates with the model to access or create data via Active Record. The create method within the sessions controller below will find the instance of User in the database by username and save the user id in the session, unless the username or password are invalid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    def create
        user = User.find_by(username: params[:username])
        if user&amp;amp;.authenticate(params[:password])
          session[:user_id] = user.id
          render json: user, status: :created
        else
          render json: { error: "Invalid username or password" }, status: :unauthorized
        end  
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Backend Model&lt;/strong&gt;&lt;br&gt;
If data is being created, the model will handle validations or return errors for invalid data. The User model in my project has validations to ensure a username is present, unique, and has at least two characters, and that the password is 2-8 characters long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ApplicationRecord
    validates :username, presence: true, uniqueness: true, length: { minimum: 2 }
    validates :password, length: { in: 2..8 }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Backend Database&lt;/strong&gt;&lt;br&gt;
Valid data will be located in the database. If data is being created, valid data will be persisted to the database as a new row in the corresponding table and assigned an ID value. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Backend Serializer&lt;/strong&gt;&lt;br&gt;
The serializer will determine which attributes will be returned in the JSON response rendered by the controller methods. My user serializer specifies that the username and user id will be returned in the JSON response. That way, only the necessary data is sent to the frontend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserSerializer &amp;lt; ActiveModel::Serializer
  attributes :id, :username
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server returns an HTTP response, which contains the JSON data, to the frontend. Using the login example, the user is now logged in and the process is complete!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>rails</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Active Record Query Methods</title>
      <dc:creator>jgifford82</dc:creator>
      <pubDate>Mon, 02 Jan 2023 22:08:27 +0000</pubDate>
      <link>https://forem.com/jgifford82/ruby-2k23</link>
      <guid>https://forem.com/jgifford82/ruby-2k23</guid>
      <description>&lt;p&gt;I'm wrapping up the third phase of my coding boot camp. In previous phases, we learned JavaScript and React. The main focus of this phase was learning Ruby. At the end of the phase, we had to complete a web project that ties everything together by building the frontend and creating a backend database. It was interesting to learn how the backend can function to organize data, which creates less work to be done on the frontend. That way, the frontend is mainly concerned with fetch requests rather than having to sort through or manipulate the data after it's fetched. The backend data organization was done using Active Record.&lt;/p&gt;

&lt;p&gt;Active Record is a big piece of what we learned in phase 3 in conjunction with Ruby. Active Record is an Object Relational Mapper, or ORM for short. This is the connection between Ruby and our database. It translates the queries we write in Ruby into commands the database understands. It's also a lot easier than writing queries in SQL, since they're written more like plain English.&lt;/p&gt;

&lt;p&gt;Active Record queries can be used to &lt;a href="https://guides.rubyonrails.org/active_record_querying.html#retrieving-objects-from-the-database" rel="noopener noreferrer"&gt;retrieve objects&lt;/a&gt; from the database, do &lt;a href="https://guides.rubyonrails.org/active_record_querying.html#calculations" rel="noopener noreferrer"&gt;calculations&lt;/a&gt;, retrieve records in a specific &lt;a href="https://guides.rubyonrails.org/active_record_querying.html#ordering" rel="noopener noreferrer"&gt;order&lt;/a&gt;, or limit records retrieved based on certain &lt;a href="https://guides.rubyonrails.org/active_record_querying.html#conditions" rel="noopener noreferrer"&gt;conditions&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Using an example from my project, I had a section where I wanted to display the ten most recently created events in the database in descending order. Here's how I did that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    get "/events" do
        events = Event.order(created_at: :desc).limit(10)
        events.to_json
    end

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

&lt;/div&gt;



&lt;p&gt;Let's break that down. The &lt;code&gt;.order&lt;/code&gt; method retrieves records from the database in a specific order. In the example, &lt;code&gt;Event.order(created_at: :desc)&lt;/code&gt; is getting a set of event records and ordering them in descending order by the created_at field in the table. The &lt;code&gt;.limit&lt;/code&gt; method is used to specify the number of records to be retrieved. In the example, &lt;code&gt;.limit(10)&lt;/code&gt; is retrieving ten records. The &lt;code&gt;.to_json&lt;/code&gt; method is used to convert a Ruby hash or array to a valid JSON string. In the example, &lt;code&gt;events.to_json&lt;/code&gt; is taking the ten event records and converting them to a JSON string for the frontend side of the application.&lt;/p&gt;

&lt;p&gt;This is what the ten most recently created events looks like on my website:&lt;/p&gt;

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

&lt;p&gt;When I first started my project, I realized I could just chain all the methods together, rather than using a variable and breaking out methods on separate lines like I did in the example above. I thought it made more sense since it was less code to write out and easier to read. I learned the hard way that while it may work, it may not always be a best practice. It may be ok with smaller, simpler code blocks like the one below. I set it up for deleting a specific event in my table by chaining together the &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;destroy&lt;/code&gt;, and &lt;code&gt;to_json&lt;/code&gt; methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    delete "/events/:id" do
        Event.find(params[:id]).destroy.to_json
    end

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

&lt;/div&gt;



&lt;p&gt;However, chaining everything together for a patch request wasn't ideal. This is what I did at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    patch "/events/:id" do 
        Event.find(params[:id]).update(
            venue: params[:venue],
            date: params[:date],
            time: params[:time]
        ).to_json
    end

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

&lt;/div&gt;



&lt;p&gt;While this was working on the backend to update an event in my table, it was giving me trouble on the frontend. The frontend patch request was console logging "true" when I was expecting it to return the updated event object. This &lt;a href="https://apidock.com/rails/ActiveRecord/Serialization/to_json" rel="noopener noreferrer"&gt;article&lt;/a&gt; helped me realize that &lt;code&gt;to_json&lt;/code&gt; returns "true" by default. Breaking out each method separately using a variable as shown below solved the problem. It's cleaner to do it this way for longer, more complex code blocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    patch "/events/:id" do 
        event=Event.find(params[:id])
        event.update(
            venue: params[:venue],
            date: params[:date],
            time: params[:time]
        )
        event.to_json
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Overall, I really enjoyed learning Ruby and Active Record! It felt more straightforward than JavaScript or React, and it's fun using the methods for organizing data. &lt;/p&gt;

&lt;p&gt;Resources:&lt;br&gt;
&lt;a href="https://guides.rubyonrails.org/active_record_basics.html" rel="noopener noreferrer"&gt;https://guides.rubyonrails.org/active_record_basics.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://guides.rubyonrails.org/active_record_querying.html" rel="noopener noreferrer"&gt;https://guides.rubyonrails.org/active_record_querying.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Controlled Forms in React</title>
      <dc:creator>jgifford82</dc:creator>
      <pubDate>Mon, 19 Sep 2022 23:08:29 +0000</pubDate>
      <link>https://forem.com/jgifford82/controlled-forms-in-react-43d0</link>
      <guid>https://forem.com/jgifford82/controlled-forms-in-react-43d0</guid>
      <description>&lt;p&gt;I'm coming to the end of my second phase of coding boot camp. This phase taught us about using the React framework, after having learned JavaScript in the first phase. I loved how much more organized React is and that it allows you to write code that looks like HTML. I found it to be a bit more user friendly, though it was a bit tricky to understand some of the ways it works. One of the trickiest things for me to understand is how to set up controlled forms, so I decided that would be the best topic for my next blog!&lt;/p&gt;

&lt;p&gt;My understanding of the benefit of controlled forms is that we have better control of user entered data since it's updated in real time using the State Hook as the user inputs it on the form. The component re-renders each time the state variable changes, rather than having to manually refresh the page. If needed, other components or elements can use state values, which is helpful if you need to render form input on the page after it’s submitted.&lt;/p&gt;

&lt;p&gt;To set up a controlled form, a state variable is needed, as well as a function that updates state when the form input changes.&lt;/p&gt;

&lt;p&gt;Before setting up state, be sure to import the state hook. Refer to the React &lt;a href="https://reactjs.org/docs/hooks-state.html"&gt;State Hook&lt;/a&gt; page for more info about state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For controlled forms, the state variable is typically used to set the default input value as an empty string to reflect the empty field before the user enters anything on the form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [inputValue, setInputValue] = useState(“”);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, set up a function that updates the state variable when the form input changes. A best practice is to have it console log the event target value when initially setting it up so you can confirm it's capturing the form input before setting up the function to update the state variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleInputValueChange(event) {
  console.log(event.target.value);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add an onChange event listener to the input element that calls the function within curly braces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
   type="text"
   name="title"
   placeholder="Title"
   onChange={handleInputValueChange}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it’s working correctly, the console log should show everything typed in the form as it’s being typed. &lt;/p&gt;

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

&lt;p&gt;Now that it’s capturing the input value, we can have it update the state variable. Instead of the console log, we need to change it to setState. In the example below, it’ll setInputValue to the event target value. If you have it console log the state variable outside of the function, you can confirm that the state variable is being updated as the user types something in the form’s input field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleInputChange(event) {
  setInputValue(event.target.value);
}

console.log(inputValue)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Now we have a basic set up for a controlled form. This can be done with each input field if there is more than one. It can also be used on other form elements, such as &lt;em&gt;select&lt;/em&gt;. When you set up a function for the submit event, you can have it set the state variable back to an empty string to clear out the user’s input from the field after they click the submit button.&lt;/p&gt;

&lt;p&gt;Hopefully this will help you make sense of controlled forms! &lt;a href="https://reactjs.org/docs/forms.html"&gt;React Forms&lt;/a&gt; is a great resource for setting up controlled forms. Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to make a fetch request</title>
      <dc:creator>jgifford82</dc:creator>
      <pubDate>Thu, 14 Jul 2022 17:28:47 +0000</pubDate>
      <link>https://forem.com/jgifford82/how-to-make-a-fetch-request-4hlh</link>
      <guid>https://forem.com/jgifford82/how-to-make-a-fetch-request-4hlh</guid>
      <description>&lt;p&gt;In the first phase of my coding boot camp, I learned how to do a fetch request. It was confusing at first, but after a bit of practice, I realized how useful it can be.&lt;/p&gt;

&lt;p&gt;A fetch request is a way of retrieving data from a database. The data can be added to the DOM after a page loads, which helps reduce rendering time. Fetch is a global method called on the window object.  &lt;/p&gt;

&lt;p&gt;There are a few different types of fetch requests, such as GET, POST, and DELETE. I’m focusing on the GET request, which was what I used for my phase 1 project. All you need to get started is a URL link to the database of your choice. &lt;/p&gt;

&lt;p&gt;A basic way to set up a fetch request is to pass the URL string in as an argument, and add a couple of .then() methods that will convert the data to JSON and log it in the console. The data needs to be converted into JSON so you can work with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch(“URL of your choice")
       .then(response =&amp;gt; response.json())
       .then(data =&amp;gt; console.log(data))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the data in the console log returned as arrays you can work with. This screenshot shows 3 nested arrays returned under object key &lt;strong&gt;results&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vm4tHgJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6iyhcjrkm55m4waxg6q.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vm4tHgJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6iyhcjrkm55m4waxg6q.JPG" alt="console log results" width="289" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you were to set up the request without converting the data to JSON, you’d only log the response from the fetch request in the console. This doesn’t provide data we can easily work with, so be sure to include a .then method that converts the fetch response data to JSON. Here’s an example of console logged data without being converted to JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch("https://www.dnd5eapi.co/api/spells/")
            .then(data =&amp;gt; console.log(data))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zDRVfPvm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta3o7zg9krjpcfx1y5je.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zDRVfPvm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta3o7zg9krjpcfx1y5je.JPG" alt="console log results not json" width="359" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the basic fetch layout, we can build out what we want to happen with the fetched data within the second .then. In my project, I set up code to display the fetched data on the web page by creating and appending elements using forEach on the nested results arrays (see below). The entire fetch request was built within a function, which is invoked when a user submits something in a search form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fetchSpells() {
        return fetch(`https://www.dnd5eapi.co/api/spells/?name=${document.getElementById("search-spells-form").value}`)
          .then(response =&amp;gt; response.json())
          .then(data =&amp;gt; data.results.forEach((element) =&amp;gt; {
            console.log(element)
            let obj = element

            const spellsDiv = document.getElementById('spells-container')

            const ul = document.getElementById('spell-name')

            const h3 = document.createElement('h3')
            h3.innerHTML = obj.name

            const a = document.createElement('a')
            a.innerHTML = `https://www.dnd5eapi.co${obj.url}`
            a.href = `https://www.dnd5eapi.co${obj.url}`

            spellsDiv.append(ul)
            ul.append(h3)
            ul.append(a)
        }))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I was trying to set up the forEach method on the fetched data, I got stuck because I set it up like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.then(data =&amp;gt; data.forEach(element =&amp;gt; console.log(element)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returned an error “data.forEach is not a function.” After a couple hours of searching online, trial and error, and frustration, I figured out the issue after talking through it with someone. We realized that the data I wanted to use was nested in the object key “results.” I just needed to add “results.” before forEach to get it to work.&lt;/p&gt;

&lt;p&gt;I also learned that it’s not necessary to state “method: GET” in that type of fetch request since that’s what it does by default. The method only needs to be stated for the other types of fetch requests.&lt;/p&gt;

&lt;p&gt;Hopefully this helps others learning about fetch requests. Happy fetching!&lt;/p&gt;

&lt;p&gt;Resource:&lt;br&gt;
“Fetch API - Web Apis: MDN.” Web APIs | MDN, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API&lt;/a&gt;.&lt;/p&gt;

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