<?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: Breon White</title>
    <description>The latest articles on Forem by Breon White (@breonwhite).</description>
    <link>https://forem.com/breonwhite</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%2F760664%2F80067fb2-b4a3-4ea8-984a-e7b3dcf64289.jpeg</url>
      <title>Forem: Breon White</title>
      <link>https://forem.com/breonwhite</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/breonwhite"/>
    <language>en</language>
    <item>
      <title>Phase-5 / Building an Online Store using Active Record Associations</title>
      <dc:creator>Breon White</dc:creator>
      <pubDate>Mon, 13 Mar 2023 07:22:53 +0000</pubDate>
      <link>https://forem.com/breonwhite/phase-5-building-an-online-store-using-active-record-associations-8j2</link>
      <guid>https://forem.com/breonwhite/phase-5-building-an-online-store-using-active-record-associations-8j2</guid>
      <description>&lt;p&gt;For my Phase 5 project, I decided to try building an online store --however, I definitely wanted this store to have a sense of community. I want users to have multiple roles. For example, as a single user, I wanted the ability to &lt;em&gt;sell&lt;/em&gt; my own items as a &lt;strong&gt;seller&lt;/strong&gt; and &lt;em&gt;purchase&lt;/em&gt; items (sold by other users) as a &lt;strong&gt;buyer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To do this, I would have to take advantage of &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html"&gt;Active Record Roles&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Active Record Roles?
&lt;/h2&gt;

&lt;p&gt;Active Record roles are a way to define different roles or user types within an application and assign specific permissions or behaviors to those roles. In a multi-role application like the online store I was building, where users may have different abilities and access levels depending on their role, Active Record roles can be a powerful tool for managing and controlling user behavior.&lt;/p&gt;

&lt;p&gt;For example, in my online sneaker store, I want to have two main user roles: &lt;code&gt;buyers&lt;/code&gt; and &lt;code&gt;sellers&lt;/code&gt;. &lt;strong&gt;Buyers&lt;/strong&gt; will be able to view and purchase products.. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yY1VYLD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5eo283x925uaw8jweah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yY1VYLD3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5eo283x925uaw8jweah.png" alt="sneaker-app-buyer-view" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While &lt;strong&gt;sellers&lt;/strong&gt; will be able to create and manage products, view total sales. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zemi2YBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jx7o2q2ke7dvfr3911w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zemi2YBu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jx7o2q2ke7dvfr3911w.png" alt="sneaker-app-seller-view" width="880" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Roles are Better
&lt;/h3&gt;

&lt;p&gt;D.R.Y. By using Active Record roles, you can easily assign these different permissions and behaviors to each role, without having to write complex authorization logic throughout your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up My Database
&lt;/h2&gt;

&lt;p&gt;Every great application has an even greater database behind it. So I started with setting up my database migration using Rails. I created this migration by adding foreign keys for the &lt;code&gt;seller_id&lt;/code&gt; and &lt;code&gt;buyer_id&lt;/code&gt; roles to my users table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate migration CreateUserRoles seller:references buyer:references
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These columns will be used to reference the User record for the seller or buyer associated with a given product listing or purchase through foreign keys.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up My Models
&lt;/h2&gt;

&lt;p&gt;In my User model, I defined the associations for the &lt;em&gt;seller&lt;/em&gt; and &lt;em&gt;buyer&lt;/em&gt; roles using the has_many method:&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
    has_secure_password

    has_many :listings, foreign_key: :seller_id
    has_many :purchases, foreign_key: :buyer_id
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting Up My Controller
&lt;/h2&gt;

&lt;p&gt;Now that I've set up my roles and associations, I can use them to implement role-based functionality in my web store application. &lt;/p&gt;

&lt;p&gt;For example, if a user is a &lt;code&gt;seller&lt;/code&gt;, they should be able to create and manage &lt;code&gt;listings&lt;/code&gt; in the store:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(&lt;em&gt;There's probably a better way to write this, but we can save that for another blog&lt;/em&gt;)&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create
        seller = current_user
        sneaker = Sneaker.create(sneaker_params)
        listing = Listing.new(listing_params)
        listing.seller_id = seller.id
        listing.sneaker_id = sneaker.id

        if listing.save
          render json: listing, status: :created
        else
          render json: listing.errors, status: :unprocessable_entity
        end
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same would go for &lt;code&gt;purchases&lt;/code&gt;. I can set up my purchases controller to associate the &lt;code&gt;buyer_id&lt;/code&gt; with the &lt;code&gt;current_user.id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pretty cool! Although this was little confusing to grasp at first, it's still great to know about this feature! From here, I can continue building special feature in my application based on the user's role.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Phase 4 - Improving User Experience using React.lazy</title>
      <dc:creator>Breon White</dc:creator>
      <pubDate>Thu, 09 Feb 2023 14:34:36 +0000</pubDate>
      <link>https://forem.com/breonwhite/phase-4-improving-user-experience-using-reactlazy-36af</link>
      <guid>https://forem.com/breonwhite/phase-4-improving-user-experience-using-reactlazy-36af</guid>
      <description>&lt;p&gt;Although a 'visually appeasing' frontend application is not really a requirement for most of our coding bootcamp projects, as a creative, I just can't help myself sometimes. Even as a junior engineer, I believe the overall user experience is important. &lt;/p&gt;

&lt;p&gt;For my recent project, &lt;a href="https://github.com/breonwhite/phase-4-project-buckit" rel="noopener noreferrer"&gt;&lt;strong&gt;Buckit&lt;/strong&gt;&lt;/a&gt;, a bucket list management app, I wanted to step it up a little by adding some background images to the app. I'm no css expert, but I found a hacky way to add background images using &lt;a href="https://mui.com/" rel="noopener noreferrer"&gt;MUI&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Box from '@mui/material/Box';
import sky1 from '../images/sky1.jpg';

&amp;lt;Box
      style={{
      backgroundImage: `url(${sky1})`,
      backgroundSize: "cover",
      height: "100vh",
      ....
    }}&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8zg6cj2przgjyxp5u3s3.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%2F8zg6cj2przgjyxp5u3s3.png" alt="signup/page" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking good, but moving slow
&lt;/h2&gt;

&lt;p&gt;Unfortunately, immediately after adding the images, the performance of the site was &lt;em&gt;very&lt;/em&gt; noticeable. Directing between pages would take a few seconds to load the background and since this project was using &lt;a href="https://guides.rubyonrails.org/security.html" rel="noopener noreferrer"&gt;Rails authentication&lt;/a&gt; between routes, I figured my application just needed a few more seconds to think. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a (DRY) Loading Page
&lt;/h2&gt;

&lt;p&gt;Since adding these background images were just a '&lt;em&gt;nice to have&lt;/em&gt;' and a bit out of scope, I didn't want to go down a rabbit hole trying to make the site overly efficient --(we can come back and do that later). However, the question still remained --how can I create a simple loading page while keeping my code clean? &lt;/p&gt;

&lt;p&gt;That's when I discovered &lt;code&gt;React.lazy&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The React.lazy function lets you render a dynamic import as a regular component...&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After reading &lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy" rel="noopener noreferrer"&gt;react's documentation&lt;/a&gt;, I got to work on my application!&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring my App.js file
&lt;/h2&gt;

&lt;p&gt;I started by importing &lt;code&gt;Suspense&lt;/code&gt; from React in my &lt;code&gt;App.js&lt;/code&gt; file:&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, { Suspense } from 'react';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I removed my importing components and assigned them to variables instead using the &lt;code&gt;React.lazy&lt;/code&gt; feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Suspense } from 'react';
import Home from './containers/Home';
import Item from './containers/item/Item';
import Items from './containers/item/Items';

function App() { ... 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

function App() {
  const Home = React.lazy(() =&amp;gt; import('./containers/Home'));
  const Item = React.lazy(() =&amp;gt; import('./containers/item/Item'));
  const Items = React.lazy(() =&amp;gt; import('./containers/item/Items'));
....
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, I wrapped everything in the &lt;code&gt;Div&lt;/code&gt; in the &lt;code&gt;Suspense&lt;/code&gt; component imported from React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {

  const Home = React.lazy(() =&amp;gt; import('./containers/Home'));
  const Item = React.lazy(() =&amp;gt; import('./containers/item/Item'));
  const Items = React.lazy(() =&amp;gt; import('./containers/item/Items'));

  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}&amp;gt; 
      &amp;lt;UserProvider&amp;gt;
      &amp;lt;Navbar /&amp;gt;
        &amp;lt;Routes&amp;gt;
          ...
      &amp;lt;/Suspense&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For now, I just went with a 'Loading...' placeholder as the fallback --but it's cool to know that you can design a custom loading page in the future if you want&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;amp; that's it! SO EASY. A few line changes in ONE file. No refactoring my &lt;code&gt;Routes&lt;/code&gt;, no impacts on my &lt;code&gt;context&lt;/code&gt; or the rest of my application. &lt;/p&gt;

&lt;p&gt;Now, when the page is loading you'll see the small 'Loading...' text for a split second. Thanks React!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
    <item>
      <title>Phase 3 - Updating and Dropping Databases using Active Record</title>
      <dc:creator>Breon White</dc:creator>
      <pubDate>Fri, 11 Nov 2022 21:46:49 +0000</pubDate>
      <link>https://forem.com/breonwhite/phase-3-updating-and-dropping-databases-using-active-record-5bob</link>
      <guid>https://forem.com/breonwhite/phase-3-updating-and-dropping-databases-using-active-record-5bob</guid>
      <description>&lt;p&gt;For this project, we had to build an application that uses Active Record to interact with a database. I decided to go with a task management application for Podcast planning titled &lt;strong&gt;Podtask&lt;/strong&gt;. This tool will allow users to document their podcast topics, featured guests, and tasks to complete for a successful episode release. &lt;/p&gt;

&lt;p&gt;One requirement for this project is that the database has to have at least two models with a &lt;strong&gt;one-to-many&lt;/strong&gt; relationship.&lt;/p&gt;

&lt;h2&gt;
  
  
  One-to-Many Relationships
&lt;/h2&gt;

&lt;p&gt;For context, in relational databases, a &lt;em&gt;one-to-many relationship&lt;/em&gt; occurs when a parent record in one table can potentially reference several child records in another table. When I started this project, I created 3 database migrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a table for Podcasts (&lt;em&gt;Parent&lt;/em&gt; Record*)&lt;/li&gt;
&lt;li&gt;a table for Tasks (&lt;em&gt;Child&lt;/em&gt; Record*)&lt;/li&gt;
&lt;li&gt;and a table for Lists, which was associated with the Podcast ID and a task ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, while working through my project, I quickly noticed that I didn't need to use the List table in the database. This is when I had to refresh my memory on how to delete a table, as well as deleting columns from a table. &lt;/p&gt;

&lt;h3&gt;
  
  
  Delete Column from Database Table
&lt;/h3&gt;

&lt;p&gt;To get started, you have to run a new migration for removing the column. The Tasks table we'll be working with first has the following build in it's migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateTasks &amp;lt; ActiveRecord::Migration[6.1]
  def change
    create_table :tasks do |t|
      t.integer :podcast_id
      t.integer :list_id
      t.string :to_do
      t.string :todo_status
      t.timestamps
    end
  end
end  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The column we will need to remove is &lt;code&gt;list_id&lt;/code&gt;. &lt;br&gt;
I ran the following code to start the migration, and made sure the name included details about the action we wanted to take place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec rake db:create_migration NAME=remove_column_from_tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the migration was created, I followed the instructions found on the &lt;a href="https://api.rubyonrails.org/v7.0.4/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-remove_column"&gt;Ruby on Rails - Active Record Migrations&lt;/a&gt; online guide. To remove a column, we will be using the &lt;code&gt;remove_column&lt;/code&gt; statement. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;remove_columns&lt;/strong&gt;(&lt;em&gt;table_name, *column_names, type: nil&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With our statement in place, this is what our migration looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class RemoveColumnFromTasks &amp;lt; ActiveRecord::Migration[6.1]
  def change
    remove_column :tasks, :list_id, :integer
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, with everything in place we can run this migration using the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bundle exec rake db:migrate  &lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Success! By checking the schema.rb file, we can confirm the column was removed. &lt;/p&gt;
&lt;h3&gt;
  
  
  Delete Column from Database Table
&lt;/h3&gt;

&lt;p&gt;For deleting an existing table, we can pretty much follow the same steps above except we would be using the &lt;code&gt;drop_table&lt;/code&gt; statement instead of the &lt;code&gt;remove_column&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;After creating a migration...&lt;br&gt;
&lt;code&gt;bundle exec rake db:create_migration NAME=drop_lists_table&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...we can set up our migration with the following build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DropListsTable &amp;lt; ActiveRecord::Migration[6.1]
  def change
    drop_table :lists
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, I ran the &lt;code&gt;bundle exec rake db:migrate&lt;/code&gt; command and checked the &lt;code&gt;schema.rb&lt;/code&gt; file - success again! Our table was removed.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Migrations Are Our Friends
&lt;/h3&gt;

&lt;p&gt;I'll admit, I was a little comprehensive about making adjustments to the database - especially after already building most of project. &lt;/p&gt;

&lt;p&gt;However, I learned that migrations aren't scary. Even with proper planning before starting a project, things happen and there are plenty of resources are your fingertips to guide you through. &lt;/p&gt;

</description>
      <category>activerecord</category>
      <category>codingbootcamp</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Phase 2 - Understanding React's RESTful Routing</title>
      <dc:creator>Breon White</dc:creator>
      <pubDate>Fri, 22 Jul 2022 16:57:42 +0000</pubDate>
      <link>https://forem.com/breonwhite/phase-2-understanding-reacts-restful-routing-1djo</link>
      <guid>https://forem.com/breonwhite/phase-2-understanding-reacts-restful-routing-1djo</guid>
      <description>&lt;p&gt;When I started building my first ever front-end application using React, I hadn't really grasped the importance of RESTful routing just yet. My application, &lt;a href="https://youtu.be/lxGmMbZmFvI" rel="noopener noreferrer"&gt;Stream-Mii&lt;/a&gt;, was a simple webform that allowed users to search for their favorite shows using a public API and assign the series to a day of the week. Users could then go back and view which shows they had planned to watch on that particular day.&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%2Ff7fvfzrq91fztxpuri19.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7fvfzrq91fztxpuri19.gif" alt="Stream-Mii"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping Routes Simple
&lt;/h3&gt;

&lt;p&gt;I remember learning that routes should be kept simple, but why? After doing some research, I learned that there is a specific (and highly appreciated) reason why routes should be kept simple - and how all of our applications are connected in a larger picture. &lt;/p&gt;

&lt;h3&gt;
  
  
  What is RESTful Routing?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt; stands for &lt;strong&gt;Representational State Transfer&lt;/strong&gt;. The formal definition for REST is '&lt;em&gt;a term exchanging data in well-defined formats in order to increase interoperability&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;What this means is that across different languages, there is a set structure in place for handling the different HTTP methods. &lt;/p&gt;

&lt;p&gt;HTTP is considered stateless, so when we navigate from one page to another in an application, HTTP doesn't retain any information between the pages. As a developer, we have to implement code to let the application know how to respond to these changes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why is REST so appreciated by developers?
&lt;/h3&gt;

&lt;p&gt;Standardization. Before REST, developers would create unique names for each route. That means that every application would have a unique structure for routes. With the number of applications available today, you can only imagine how unsustainable this approach was. However, REST really showcases how connected our applications are. &lt;/p&gt;

&lt;p&gt;When you think about everything that we do on the web, it's hard to believe that all of those things can be boiled down to 7 primary actions. This helped me structure &lt;a href="https://github.com/breonwhite/phase-2-project-stream-mii/blob/master/src/App.js" rel="noopener noreferrer"&gt;my routes for Stream-Mii&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- GET: (/shows - returns a collection of saved shows)
- NEW: (/shows/new - returns a form to add a new show)
- POST: (/shows/new - saves a new show to the database)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this structure, if I wanted to build on to my application in the future, I could use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- SHOW: (/shows/:id - returns an existing show with the show details)
- EDIT: (/shows/:id/edit - returns a form to edit an existing show)
- PATCH: (/shows/:id - updates an existing show in the database)
- DELETE: (/shows/:id - deletes an existing show)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>restfulroutes</category>
      <category>beginners</category>
      <category>bootcamp</category>
    </item>
    <item>
      <title>Phase-1 Project: CAP KEEPS</title>
      <dc:creator>Breon White</dc:creator>
      <pubDate>Thu, 24 Feb 2022 05:26:30 +0000</pubDate>
      <link>https://forem.com/breonwhite/cap-keeps-phase-1-project-g7n</link>
      <guid>https://forem.com/breonwhite/cap-keeps-phase-1-project-g7n</guid>
      <description>&lt;p&gt;"&lt;em&gt;Find, save, and easily create photo captions in minutes. No cap.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;As a student at Flatiron School, for my Phase-1 project I created a front-end web application that allows music and social media enthusiast to save Instagram captions for future posts using either song lyrics returned from a public API or manually entered to create custom captions of their own. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;BACKSTORY&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You've picked the perfect post-worthy picture, now you're left with the question "&lt;em&gt;What should my caption be?&lt;/em&gt;" This is a question I hear way too often amongst my group of friends. With a &lt;a href="https://www.google.com/search?q=instagram+captions&amp;amp;rlz=1C5CHFA_enUS978US978&amp;amp;oq=instagram+captions&amp;amp;aqs=chrome..69i57j0i512j0i433i512j0i131i433i512j0i512l2j0i433i512j0i512l3.3543j0j9&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8"&gt;quick Google search&lt;/a&gt;, you can see there are &lt;em&gt;thousands&lt;/em&gt; of websites catered to Instagram captions alone and it's no secret that song lyrics make some of the &lt;strong&gt;best&lt;/strong&gt; captions. This tool I created removes the extra decision making and researching before your next Instagram post. You can access your personal vault of save captions with ease.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;HOW IT WORKS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When searching for captions using CAP KEEPS, users can input a string of words in the front-end web form. CAP KEEPS takes that string and generates a custom URL that is used in a Fetch method directly to &lt;a href="https://genius.com/"&gt;Genius Lyrics&lt;/a&gt; API, a public lyric database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3IEzXMlu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4sl3i6lw52ic88hp1h0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3IEzXMlu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4sl3i6lw52ic88hp1h0.gif" alt="GIF of CAP KEEPS expected behaviors" width="880" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fetch request returns the 5 top lyric results in an array. The tools then maps through that array and creates an object using the returned lyric snippet, song, artist, and artist image which are then displayed in an unordered list to the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WdR0AphI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xq7dneh4rskze2qxap6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WdR0AphI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xq7dneh4rskze2qxap6.png" alt="Preview of captions returned from search results" width="880" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a user, you have that option to '&lt;em&gt;Keep&lt;/em&gt;' or '&lt;em&gt;Unkeep&lt;/em&gt;' captions returned in the search results. Kept captions are pushed to the database (and when you '&lt;em&gt;Unkeep&lt;/em&gt;' a caption, it's removed from the database).&lt;/p&gt;

&lt;p&gt;When you click on "My Captions", similar behavior happens when search results are returned. For each caption stored in the database, it creates an HTML element using the object data and appends it to an unordered list. Here, users can manage their saved captions which includes favoriting ('&lt;em&gt;Like&lt;/em&gt;' heart), copying lyrics to the clipboard, or deleting the caption (which uses a method to remove the HTML element and delete the caption from database).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yrcPtbox--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8g4dqg9y6prwumt6d0xh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yrcPtbox--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8g4dqg9y6prwumt6d0xh.png" alt="Users can interact with saved captions under 'My Captions'" width="880" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;OVERCOMING OBSTACLES&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At first attempt, fetching data from a public API was a little intimidating. I used &lt;a href="https://rapidapi.com/"&gt;Rapid API&lt;/a&gt; for the first time, a public API hub that was very beginner-friendly. Rapid API allows you to test endpoints and preview the type of response you would receive from the fetch request. This gave me the opportunity to experiment and get an idea for the method I would I need to create for mapping through this response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SDKiAt6h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6qwxkc2h5j6147a37lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SDKiAt6h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6qwxkc2h5j6147a37lw.png" alt="Rapid API" width="880" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to generate the URL for the fetch request to Genius API, I had to create a special method that takes the string provided in the input field and replaced spaces with '%20' (thank you late night Google searches!). An example of the code I mimicked can be found &lt;a href="https://www.codespeedy.com/how-to-replace-space-with-20-in-javascript/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TAKEAWAYS&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It doesn't have to look nice right away, just get it to work! (MVP and Pseudo&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;I've always been big on presentation but during this process, the MVP technique was my savior. Step by step, I would write out exactly what I was trying to do, when I wanted this to happen in my code. As my code grew longer and longer, going back to the MVP technique really helped me get my thoughts down and stay organized. There's always time to go back and clean things up. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set boundaries and know when to ask for help.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;I love programming, but almost &lt;em&gt;too&lt;/em&gt; much sometimes. During this project, when I was deep in a solve, I found myself spending hours diving through resources to find a solution. I learned how important it is to stop and know when to ask for help or get a second opinion (no matter how much fun you're having trying to find the answer on your own). Having my MVP written out made it even easier to ask questions since I knew exactly what I was trying to do. Time management and asking questions is key for productivity. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Methods save so much time.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Working on this project really highlighted how repetitive code can be when you're writing it. I learned there's almost always a flexible method you can create to handle almost anything for your app. I'm excited to continuing building on these skills to have clean code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're interested in viewing CAP KEEPS, checkout my repo: &lt;a href="https://github.com/breonwhite/phase-1-project-cap-keeps"&gt;https://github.com/breonwhite/phase-1-project-cap-keeps&lt;/a&gt;&lt;br&gt;
Youtube: &lt;a href="https://youtu.be/OSLuZkXDnXQ"&gt;https://youtu.be/OSLuZkXDnXQ&lt;/a&gt; &lt;/p&gt;

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