<?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: dgvall</title>
    <description>The latest articles on DEV Community by dgvall (@dgvall).</description>
    <link>https://dev.to/dgvall</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%2F950935%2F8b6649a9-4b78-4679-9fc0-19f803acf28f.png</url>
      <title>DEV Community: dgvall</title>
      <link>https://dev.to/dgvall</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dgvall"/>
    <language>en</language>
    <item>
      <title>Fighting Game Notation Made Easy</title>
      <dc:creator>dgvall</dc:creator>
      <pubDate>Sun, 28 May 2023 23:10:25 +0000</pubDate>
      <link>https://dev.to/dgvall/fighting-game-notation-made-easy-472n</link>
      <guid>https://dev.to/dgvall/fighting-game-notation-made-easy-472n</guid>
      <description>&lt;p&gt;Fighting games require complex button combinations to execute "combos." To share combos with fellow enthusiasts, we use "numpad notation," which associates the numbers on a standard nine-button number pad with a direction (Down is 2, Forward is 6, Up is 8, etc.). However, deciphering numpad notation can be challenging for newcomers. Given that fighting games have the reputation of being unwelcoming for new players, I wanted to work to make combo notation one less barrier for entry. In this blog, we will explore my "Combo Builder" that simplifies notation through the process of converting fighting game numpad notation into easy-to-read, digestible images with recognizable iconography.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Combo Builder Interface:
&lt;/h2&gt;

&lt;p&gt;The Combo Builder is a dynamic upload interface where users can notate their own combos. Each button on the interface represents a button press in the game and will have the same appearance as the corresponding in-game button.&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%2Fzi3vce8vswpupvmukqej.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%2Fzi3vce8vswpupvmukqej.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;2P 6P 236S notated through the combo builder&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These input buttons are saved on the backend where a Game has many inputs. For example, the "P" button (Punch) is saved as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input.create!(
  input_type: "Button",
  name: "P",
  image_url: "https://i.imgur.com/Dv8VQDw.png"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This input has a type value of "Button," which corresponds to its position in the builder (Directions, Motions, Universal, Buttons, Game-specific notation). Additionally, the name "P" is how this input would be normally notated, and the image URL is the iconography used in the game to depict this button press.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling User Interaction:
&lt;/h2&gt;

&lt;p&gt;Once inputs are fetched and organized by their type, the user is able to create their combo notation by clicking inputs. During the combo creation process, two types of data are saved: an array of image URLs and a string of inputs. The array of image URLs only exists on the frontend for creation while the string of inputs is saved in the backend for later use.&lt;/p&gt;

&lt;p&gt;The handleClick function adds a new button to the combo. It takes the source URL of the button's image and the corresponding button name as parameters. The function appends the source URL to the imageUrls array and updates the inputs string by adding the button name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleClick(src, name) {
    setImageUrls(() =&amp;gt; [...imageUrls, src])
    if (inputs.length &amp;gt; 0) {
      setInputs(() =&amp;gt; `${inputs} ${name}`)
    }
    else setInputs(name)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The handleSpace function adds an empty image and a hyphen ("-") to represent space between inputs. It helps improve the readability of the combo notation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function handleSpace() {
    // set spaceUrl from game data later!
    const spaceUrl = "https://i.imgur.com/IxEwf4u.png"
    setImageUrls(() =&amp;gt; [...imageUrls, spaceUrl])
    setInputs(() =&amp;gt; `${inputs} -`)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Combo Builder also includes functionality for clearing the input progress and removing the most recently added input. These make for great quality of life improvements for the user experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function handleClear() {
    setImageUrls([])
    setInputs("")
  }

  function handleBackspace() {
    const updatedImageUrls = imageUrls.slice(0, imageUrls.length - 1)
    setImageUrls(updatedImageUrls)

    const inputsArray = inputs.split(" ")
    const updatedInputs = inputsArray.slice(0, inputsArray.length - 1).join(" ")
    setInputs(updatedInputs)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Serialization and Image URL Mapping:
&lt;/h2&gt;

&lt;p&gt;Though only inputs are saved on the backend, during the combo serialization process we send the user the array of image URLs. This method splits the inputs string by spaces and maps each input to its corresponding image URL. By using a case statement, the appropriate image URL is assigned based on the input value, in the exact order they were saved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def image_urls
    object.inputs.split(' ').map do |input|
      case input
        when '1'
          'https://i.imgur.com/Fby15hF.png'
        when '2'
          'https://i.imgur.com/KezFbHr.png'
        when '3'
          'https://i.imgur.com/06D3AyK.png'
        when '4'
          'https://i.imgur.com/HwKpXDr.png'
        when '5'
          'https://i.imgur.com/OfO6HKV.png'
        ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet showcases various cases for different input values, including numeric inputs for directions and motions (according to standard numpad notation), and game-specific inputs. This approach allows for easy modification and addition of new image URLs in the future, providing flexibility and scalability to the Combo Builder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Guilty Gear Strive Combo
&lt;/h3&gt;

&lt;p&gt;Numpad notation:&lt;br&gt;
c.S 2H 486H 66 2K 268H&lt;/p&gt;

&lt;p&gt;Inputs string saved:&lt;br&gt;
c. S - 2 H - 486 H - 6 6 - 2 K - 268 H&lt;/p&gt;

&lt;p&gt;Serialized Output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2snf7sdbqc206ileqnjn.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%2F2snf7sdbqc206ileqnjn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Street Fighter 6 Combo
&lt;/h3&gt;

&lt;p&gt;Numpad notation:&lt;br&gt;
DR 2MP 2HP 214[MP] DR HP 214[LP] 236LKLK 236236HK&lt;/p&gt;

&lt;p&gt;Inputs string saved:&lt;br&gt;
DR - 2 MP - 2 HP - 214 [ MP ] - DR - HP - 214 [ LP ] - 236 LK LK - 236 236 HK&lt;/p&gt;

&lt;p&gt;Serialized Output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y9ikqqpbauhgyj0zxjo.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%2F2y9ikqqpbauhgyj0zxjo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This Combo Builder provides a user-friendly interface for creating and visualizing fighting game combos. It is a smaller piece of a larger project I'm working on called the Combo Library which will act as a hub for fighting game players to upload their combos (on a per game, per character basis) using this digestible notation.&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%2Fstb1faxl5wkq6vpqfejd.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%2Fstb1faxl5wkq6vpqfejd.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ruby on Rails - The Strengths of Convention Over Configuration</title>
      <dc:creator>dgvall</dc:creator>
      <pubDate>Tue, 11 Apr 2023 04:36:31 +0000</pubDate>
      <link>https://dev.to/dgvall/ruby-on-rails-the-strengths-of-convention-over-configuration-3l40</link>
      <guid>https://dev.to/dgvall/ruby-on-rails-the-strengths-of-convention-over-configuration-3l40</guid>
      <description>&lt;p&gt;Ruby on Rails is a super popular web development framework that's all about &lt;strong&gt;Convention over Configuration.&lt;/strong&gt; In other words, the framework follows a set of conventions so that developers don't have to specify every little detail themselves. This approach makes development way easier, reduces errors, and speeds up the whole process. Let's take a look at the benefits of Convention over Configuration in Ruby on Rails and how it helps developers out.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI Commands for Generators
&lt;/h3&gt;

&lt;p&gt;One of the biggest perks of Ruby on Rails' Convention over Configuration is the use of Command Line Interface (CLI) commands for generators. These commands automatically create different parts of the application, like controllers, models, views, and migrations.&lt;/p&gt;

&lt;p&gt;For example, you can use the "rails new" command to create a new application, which sets up a default file structure with directories for models, views, and controllers. This means you can dive right into the application without worrying about the initial setup.&lt;/p&gt;

&lt;p&gt;Similarly, you can use the "rails g" command to generate different components of the application. You can use "rails g controller" to make a new controller, "rails g model" to create a new model, and "rails g migration" to create a new database migration.&lt;/p&gt;

&lt;p&gt;These CLI commands save you so much time and effort, and make it less likely you'll make mistakes. I can't stress this point enough, it really helps you focus on the important parts of the application and let the framework take care of the boring parts.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Structure and Separation of Concerns
&lt;/h3&gt;

&lt;p&gt;Another benefit of Ruby on Rails' Convention over Configuration is the standard file structure and separation of concerns between the Model, View, and Controller (MVC) components. The MVC pattern divides the application into three different parts that handle different parts of the application.&lt;/p&gt;

&lt;p&gt;The Model component deals with the data and business logic of the application. It stores the data and provides a way to interact with it. The View component handles the user interface and shows the data to the user. The Controller component connects the Model and View components and manages the flow of information between them.&lt;/p&gt;

&lt;p&gt;Ruby on Rails follows a set of conventions for the file structure of these components, which makes it easier to understand and navigate the codebase. For instance, all models go in the "/app/models" directory, all views go in the "/app/views" directory, and all controllers go in the "/app/controllers" directory.&lt;/p&gt;

&lt;p&gt;This separation of concerns means that each component is responsible for one specific part of the application, which reduces the likelihood of human error and makes it easier to read and maintain the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customization and Flexibility
&lt;/h3&gt;

&lt;p&gt;Although Ruby on Rails follows a set of conventions, developers can still customize and modify the framework to fit their needs. You can override the default behavior by specifying your own configuration files and adding custom code.&lt;/p&gt;

&lt;p&gt;For example, you can change the default routes by adding your own routes in the "/config/routes.rb" file. Below are my routes on a project I recently completed. The "resources" code at the top is a conventional way to route common requests to a specified controller and controller action with a conventional path. Below that is customized code that I configured to route uncommon paths while still specifying a corresponding controller and controller action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resources :tags, only: [:index]
  resources :artworks, only: [:create, :index, :update, :destroy]
  resources :user_likes, only: [:create, :destroy]

  post "/signup", to: "users#create"
  get "/me", to: "users#profile"
  get '/users/:username', to: 'users#show'

  get '/tags/:name', to: 'tags#filtered'

  post "/login", to: "sessions#create"
  delete "/logout", to: "sessions#destroy"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, you can also create your own configuration files in the "config" directory, like "/config/application.rb," and"/config/database.yml" to customize the default behaviors of Rails.&lt;/p&gt;

&lt;p&gt;This customization and flexibility mean that you can tailor the framework to your specific needs while still following the conventions. You can create the application you want without being restricted by the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Overall, Convention over Configuration is a powerful concept that makes Ruby on Rails a great web development framework. By following a set of conventions, Ruby on Rails simplifies development, reduces errors, and makes it easier to maintain the application.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Getting started in back-end development</title>
      <dc:creator>dgvall</dc:creator>
      <pubDate>Tue, 14 Feb 2023 05:53:47 +0000</pubDate>
      <link>https://dev.to/dgvall/getting-started-in-back-end-development-18n3</link>
      <guid>https://dev.to/dgvall/getting-started-in-back-end-development-18n3</guid>
      <description>&lt;p&gt;I've spent the last few months learning about back-end development and I thought I'd share some big picture concepts to help others that want to learn. Even if it's outside of your wheelhouse, learning back-end development can give you a deeper understanding of how web applications work as a whole. It allows you to see the full picture and how front-end and back-end components work together to create a cohesive user experience. &lt;/p&gt;

&lt;h2&gt;
  
  
  Understand the purpose of relational databases
&lt;/h2&gt;

&lt;p&gt;Relational databases are the backbone of most modern web applications. They are designed to store and manage structured data, and they allow developers to create, read, update, and destroy that data with ease. The key to working effectively with relational databases is to understand their purpose and how they are structured.&lt;br&gt;
Relational databases are organized into tables, which are composed of rows and columns. Each row represents a single record, while each column represents a particular attribute of that record. For example, in a database of users, each row would represent a single user, while the columns would contain attributes such as the user's name, email address, and date of birth.&lt;/p&gt;
&lt;h2&gt;
  
  
  Learn SQL
&lt;/h2&gt;

&lt;p&gt;Structured Query Language (SQL) is the language used to interact with relational databases. As a back-end developer, it's important to have a good understanding of SQL and how to use it to manipulate data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understand data relationships
&lt;/h2&gt;

&lt;p&gt;One of the key concepts in relational databases is data relationships. Note that primary keys are generated when a new row of data is created. A foreign key is a reference to the primary key from a different table to establish a relationship between the two tables. &lt;/p&gt;

&lt;p&gt;There are several types of relationships, but the most common are one-to-one, one-to-many, and many-to-many. Understanding these relationships is crucial to designing a functional, manipulatable database.&lt;/p&gt;

&lt;p&gt;In a one-to-one relationship, each record in one table is associated with a single record in another table. For example, in a database of employees and their job titles, each employee would have a single job title, and each job title would be associated with a single employee. This means that one table would have a foreign key column referencing a row's primary key in the other table.&lt;/p&gt;

&lt;p&gt;In a one-to-many relationship, each record in one table is associated with multiple records in another table. For example, I recently created a to-do list where I used the tables: "Sublists" and "Tasks". A sublist has many tasks and a task belongs to one sublist. To establish this relationship, I  added a "sublist_id" foreign key column to the "Tasks" table that references the primary key column in the "Sublists" table.&lt;/p&gt;

&lt;p&gt;Relevant schema:&lt;br&gt;
Note: primary keys are built automatically and the foreign key column "sublist_id" references a specific row or data inside of the "sublists" table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create_table "sublists", force: :cascade do |t|
    t.string "name"
  end

  create_table "tasks", force: :cascade do |t|
    t.string "text"
    t.boolean "priority"
    t.integer "sublist_id"
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a many-to-many relationship, multiple records in one table are associated with multiple records in another table. Let's say an e-commerce database has two tables: "Customers" and "Products". A customer can purchase multiple products, and a product can be purchased by multiple customers. To map out this relationship, you would create a third table, "Orders", that has columns for BOTH foreign keys: "customer_id" and "product_id". Each row in the "Orders" table represents a relationship between a customer and a product that they purchased.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use an ORM
&lt;/h2&gt;

&lt;p&gt;Object-Relational Mapping is a programming technique that maps database tables to object-oriented programming languages. An ORM allows you to work with a database using object-oriented code instead of writing SQL queries directly. This can make working with relational databases more intuitive and efficient.&lt;br&gt;
In my time learning back-end development, I used Ruby which has an ORM called Active Record that maps database tables to Ruby classes. Using an ORM can simplify the process of working with a relational database and make your code more maintainable.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Learning React made it easier to code</title>
      <dc:creator>dgvall</dc:creator>
      <pubDate>Mon, 12 Dec 2022 21:42:53 +0000</pubDate>
      <link>https://dev.to/dgvall/learning-react-made-it-easier-to-code-2kf6</link>
      <guid>https://dev.to/dgvall/learning-react-made-it-easier-to-code-2kf6</guid>
      <description>&lt;p&gt;I've been learning to make websites over the last several months and I give a lot of props (haha, get it?) to React for my latest stretch of improvement. I just completed my second website and the experience was much smoother than my first.&lt;/p&gt;

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

&lt;p&gt;My biggest issue in my first website (written in Vanilla JavaScript) was the legibility of my code. The website was completely functional and bug free (as far as I know), but the code left a lot to be desired. Functions were handling multiple tasks in the effort to make them more "flexible" and there were many redundancies all over the board.&lt;/p&gt;

&lt;p&gt;After spending some time learning React it was time to complete another website. My ability to write JavaScript logic didn't vastly improve in this time, but by virtue of using React Components I had corrected all of the issues I was having with organization.&lt;/p&gt;

&lt;p&gt;A React Component is simply a reusable bunch of code with it's own individual JSX (functionally HTML), logic (JavaScript), and styling (CSS). Because components are stand alone, it becomes easier for me to just get into it and start making an individual piece to the puzzle that is a website. More importantly though, it gave me practice in keeping my code focused, organized, and legible. Additionally, when I want to make a component "flexible" and reusable, I can do so passing props to my component to conditionally change the component without any sacrifices to focus or legibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  I love State
&lt;/h2&gt;

&lt;p&gt;State is a very powerful kind of variable. So much so that you should pay attention to where you declare it for maximum efficiency. Where does this power come from? State holds data and dynamically re-renders the component whenever it changes.&lt;/p&gt;

&lt;p&gt;Here is an interesting way that I used state in my most recent website&lt;/p&gt;

&lt;h3&gt;
  
  
  State with useEffect
&lt;/h3&gt;

&lt;p&gt;We use GET requests to receive data from a server. The useEffect hook is a common way to do a GET Request when a website first loads and then save that data to a state variable. The useEffect hook ALSO has an optional second parameter that allows us to run the useEffect function every time a specific state changes. Here's how I used this in my project.&lt;/p&gt;

&lt;p&gt;1) So when my website loads, it will fetch my data at "&lt;a href="http://localhost:3000/pets"&gt;http://localhost:3000/pets&lt;/a&gt;" from my local json server, convert the response from json, shuffle the array of data, then set this data to equal my "shuffledPets" state which I will use in a variety of ways throughout my project.&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("http://localhost:3000/pets")
    .then(res =&amp;gt; res.json())
    .then(data =&amp;gt; setShuffledPets(shuffle(data)))
  }, [reshuffle])

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

&lt;/div&gt;



&lt;p&gt;More importantly, that second parameter in my useEffect function is a state called "reshuffle". Whenever this state changes, it will trigger a new GET request to pull the most up to date information, and reshuffle my array of pets.&lt;/p&gt;

&lt;p&gt;2) This isn't really relevant to React, but I used the Fisher-Yates algorithm to shuffle the array randomly.&lt;br&gt;
&lt;/p&gt;

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

    const array = [...arr]

    for (let i = array.length - 1; i &amp;gt; 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      const temp = array[i];
      array[i] = array[j];
      array[j] = temp;
    }
    return array
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) I then created a function called onReshuffle that changes the value of the reshuffle state which I then passed down as props to other components so that I could trigger a reshuffle on certain actions and conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function onReshuffle() {
    setReshuffle(() =&amp;gt; !reshuffle)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Here's an example of how one way I conditionally reshuffled my array.&lt;/p&gt;

&lt;p&gt;My website displays two pets from the array. The user clicks one to give a "like" to that pet. When the user gets to the end of the array of pets, a reshuffle is triggered.&lt;/p&gt;

&lt;p&gt;Note: I used .slice(start, end) on my array of pets to display two at a time. The start and end states change on click to move to the next pet. When the user reaches the end of the array and the second parameter of .slice() is greater than the length of the array, it changes the reshuffle state and resets the display to .slice(0,2), the beginning of the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(end &amp;gt; shuffledPets.length) {
        onReshuffle()
        setStart(0)
        setEnd(2)
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;Just wanted to talk about my progression as a coder and how much I'm loving React. Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Completing my first project as a beginner</title>
      <dc:creator>dgvall</dc:creator>
      <pubDate>Fri, 21 Oct 2022 08:11:53 +0000</pubDate>
      <link>https://dev.to/dgvall/completing-my-first-project-as-a-beginner-1mm9</link>
      <guid>https://dev.to/dgvall/completing-my-first-project-as-a-beginner-1mm9</guid>
      <description>&lt;p&gt;3 months ago, I had no experience in coding. Though I had zero understanding of what it was to code, it just felt like something I could be good at so I signed up for a boot camp and have just completed my first project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Project
&lt;/h2&gt;

&lt;p&gt;I was tasked to create a Single Page Application using JavaScript, HTML, and CSS. I wasn't married to any idea, but I knew I wanted to create something that I would actually use. I decided to move forward with a basic media listing application that uses a free API of existing TV shows to archive and categorize what a user: has watched, plans to watch, and scores the watched media. There is a similar application built into IMDB but it's incredibly limited. I wanted to make my iteration of this idea intuitive, functional, and appealing. &lt;strong&gt;I gave myself one week to complete this project.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes
&lt;/h2&gt;

&lt;p&gt;This being my first time creating something, I was eager to begin. I had an idea for how I would do everything in my head, but I never formally organized the infrastructure of this application before starting. I told myself I'd make a minimum viable product and then go from there. Once I got to this point, I fell into a dangerous loop of telling myself that I would continue building functionality and refactor code later.&lt;/p&gt;

&lt;p&gt;A week came and went and though I was able to get all of the functionality that I wanted out of this project, the code wasn't as clean as I'd hoped.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Married to JSON
&lt;/h3&gt;

&lt;p&gt;I had already learned how to initialize a JSON server as a means to save and update data. It wasn't until completing my project that I considered alternatives that would better suit my application. I actually planned on using this myself to archive a list of my favorite TV shows, but going through the hassle of initializing a server to do so makes it inconvenient to use. Given that there isn't much data that needs to be stored, I likely could have just used an object, or searched for other, more convenient, storage solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Separation of duties among functions
&lt;/h3&gt;

&lt;p&gt;It is important to me that my code is legible, flexible, and functional. I created one function in particular that I believed at the time was sacrificing some legibility for more flexibility. I see now that I needed to separate these duties among multiple functions.&lt;/p&gt;

&lt;p&gt;This function was not only asynchronously creating a modal box and overlay with all the bells and whistles, but was also filling data from both the API and the JSON server, and doing an additional fetch to determine the episode count of a particular show. This led to JavaScript processing redundant information, being difficult to read, and being difficult to debug. Due to this oversight, I had to come up with solutions that, although they may work, are less optimal than it otherwise could be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning as I go
&lt;/h2&gt;

&lt;p&gt;Although my mistakes did cost me an optimal final product, I was definitely learning from my mistakes as I continued the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Making it work
&lt;/h3&gt;

&lt;p&gt;Due to the way my modal function was written and not having the time to refactor it, I had to find a way to balance a function that receives different data under the same argument. I decided to use an OR operator when declaring a variable with this data so that I could avoid conflicts of information. In one instance, I had to use a nested if statement to make this work. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: Whenever totalepisodes is undefined, epCount will be correct. Whenever totalepisodes is defined, epCount will be incorrect. This is because the IDs between the JSON and API are not shared.&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; // Episodes determined by db.json
  console.log(show.totalepisodes)
  // Episodes determined by API
  console.log(epCount)

  const epInput = document.createElement("input")
  epInput.type = "number"
  epInput.name = "number"
  epInput.min = 0
  epInput.max = show.totalepisodes || epCount
  epInput.addEventListener("change", (e) =&amp;gt; {
    if(!show.totalepisodes) {
    if (episodes.childNodes[1].value &amp;gt;= epCount) {
      select.value = "Completed"
    }
  }
    if (episodes.childNodes[1].value &amp;gt;= show.totalepisodes) {
      select.value = "Completed"
    }
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Flexibility done right
&lt;/h3&gt;

&lt;p&gt;When I was writing the code to render filtered shows determined by status (watching, planning, etc.), I made sure to do it right. Rather than creating a function that makes a bunch of empty divs and then fills them conditionally, I created the empty divs in HTML and now I could use one function to fill ALL of them conditionally. This is a legible, flexible, and functional solution that I was very proud to find.&lt;/p&gt;

&lt;p&gt;Creates cards to a specified container id, based on the condition of an existing element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function filterBy(status, id) {
  fetch("http://localhost:3000/shows")
    .then((res) =&amp;gt; res.json())
    .then((data) =&amp;gt; {
     let filteredShows = data.filter((element) =&amp;gt; element.status === status)
     for(show of filteredShows) {
      createCards(show, id)
    }
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creates header for rendered cards&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createTitle(headText, headId) {
  let container = document.getElementById(headId)
  let header = document.createElement("h1")
  header.className = "filter-header"
  header.textContent = headText
  container.appendChild(header)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Application of functions during list creation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createList() {
  fetch("http://localhost:3000/shows")
  .then((res) =&amp;gt; res.json())
  .then((data) =&amp;gt; {
if(data[0] === undefined) {
  createTitle("Search for your favorite shows to start your list!", "watching-head")
} else {
  createTitle("Watching", "watching-head")
    filterBy("Watching", "watching-container")

    createTitle("Completed", "completed-head")
    filterBy("Completed", "completed-container")

    createTitle("Planning", "planning-head")
    filterBy("Plan to watch", "planning-container")

    createTitle("Dropped", "dropped-head")
    filterBy("Dropped", "dropped-container")
}
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Not making the same mistake twice
&lt;/h2&gt;

&lt;p&gt;This experience taught me that having a plan is vital to keeping your code optimal. As soon as I get something to work, I should refactor it immediately to benefit the code in legibility, flexibility, and functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dgvall/my-media-list"&gt;GitHub Link&lt;/a&gt;&lt;/p&gt;

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

</description>
    </item>
  </channel>
</rss>
