<?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: bperez3237</title>
    <description>The latest articles on DEV Community by bperez3237 (@bperez3237).</description>
    <link>https://dev.to/bperez3237</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%2F831274%2F37e7dafa-9a6e-4cbd-9fb2-40e876cdea57.png</url>
      <title>DEV Community: bperez3237</title>
      <link>https://dev.to/bperez3237</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bperez3237"/>
    <language>en</language>
    <item>
      <title>Import Xlsx into React</title>
      <dc:creator>bperez3237</dc:creator>
      <pubDate>Fri, 16 Sep 2022 00:08:05 +0000</pubDate>
      <link>https://dev.to/bperez3237/import-excel-into-react-12h6</link>
      <guid>https://dev.to/bperez3237/import-excel-into-react-12h6</guid>
      <description>&lt;p&gt;For my latest react web application, I wanted to create an app to assist a workflow at my construction project. Because '.xlsx' files are very common on the project, I needed to be able to work with data from these files. My plan was to import data from excel sheet to create objects in the back end that would show up in my app. &lt;/p&gt;

&lt;p&gt;I found a javascript package xlsx that would allow me to read the xlsx data once I selected the file. To setup the module:&lt;/p&gt;

&lt;p&gt;In the command line:&lt;br&gt;
&lt;code&gt;npm install xlsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At the top of the project:&lt;br&gt;
&lt;code&gt;var xlsx = require("xlsx")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this, I would now be able to call xlsx.read() which would convert the raw file data into javascript code. &lt;/p&gt;

&lt;p&gt;So I need a react component that can upload the file, and parse the data into usable js code. This js code would be used to POST objects to the backend. &lt;/p&gt;

&lt;p&gt;First, to upload the file, my basic react component would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Upload() {
     function handleFile(e) {
          e.preventDefault()
          if (e.target.files) {
          // read xlsx data
          }

     }

     return(
          &amp;lt;form&amp;gt;
               &amp;lt;input type="file" onChange={}&amp;gt;&amp;lt;/input&amp;gt;
          &amp;lt;/form&amp;gt;
     )
}

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

&lt;/div&gt;



&lt;p&gt;To read the file data, I used FileReader() to access the contents of the files selected with the input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const reader = new FileReader()

reader.onload = (e) =&amp;gt; {
     const data = e.target.result
     const workbook = xlsx.read(data, {type: "array})
     // organize xlsx data into desired format

}
reader.readAsArrayBuffer(e.target.files[0])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workbook has many ways to parse the information. I iterate through the sheets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workbook.SheetNames.forEach((sheet)=&amp;gt;{
     const worksheet = workbook.Sheets[sheet]
     // format object
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many ways to go from here: worksheet will return an object with keys for all the cells in the xlsx file. These cell labels are based on the x and y position: A,B,C... for the x axis and 1,2,3... for the y axis.&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%2Fmsue30gu5srk5hmlzynh.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%2Fmsue30gu5srk5hmlzynh.png" alt="Image description" width="708" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get the value of cell 'B1' in the worksheet, call:&lt;br&gt;
&lt;code&gt;worksheet.B1.v&lt;/code&gt;&lt;br&gt;
or&lt;br&gt;
&lt;code&gt;worksheet['B1']['v']&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this kind of data structure, it's possible to go through the xlsx sheet dynamically. A nested for loop to go through the data row by row or column by column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (let row = 1; row &amp;lt; lastRow ; row++) {
     for (let column = 'A'; column &amp;lt; lastColumn; column++) {
          cellValue = worksheet[`${column}${row}`]['v']
          // do something with cell value
     }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this sounds easy, the code block above wouldn't work for a couple reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;lastRow and lastColumn aren't known values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;column++ does not work since the increment operator doesn't work on 'A'&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Taking a look at number 1 first:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting the value of the lastRow and lastColumn could be done using a custom max function. Javascript can interpret string comparisons like:&lt;br&gt;
&lt;code&gt;'B' &amp;gt; 'A' ==&amp;gt; true&lt;/code&gt;&lt;br&gt;
&lt;code&gt;'A' &amp;gt; 'B' ==&amp;gt; false&lt;/code&gt;&lt;br&gt;
&lt;code&gt;'A1' &amp;gt; 'D1' ==&amp;gt; false&lt;/code&gt;&lt;br&gt;
&lt;code&gt;'D2' &amp;gt; 'D1' ==&amp;gt; true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With this logic, a maxCell function could be created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function maxCell(cell1, cell2) {
    if (cell1 &amp;gt; cell2) {
        return cell1
    } else {
        return cell2
    } 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to extend this over an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function maxArray(array) {
        var max = ''
        array.forEach((elem)=&amp;gt;{
            max = maxCell(max, elem)
        })
        return max
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the keys of worksheet are all the cell values, calling:&lt;br&gt;
&lt;code&gt;maxArray(Object.keys(worksheet))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;would return the largest cell label. And using the largest cell label, the string can be spliced to get the last row and column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const largestCell = 'E8'
const lastRow = largestCell.slice(1)
const lastColumn = largestCell.slice(0,1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Taking a look at number 2:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While it isn't as simple as 'A' + 1 = 'B', using the String object methods this is pretty easy. Strings have a method charCodeAt() that will return their UTF-16 character code. So I just need to convert to the character code, increment by 1, and then convert back to a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function nextChar(letter) {
        return String.fromCharCode(letter.charCodeAt(0) + 1);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I was originally building out my project, this was the thought process I followed. And I thought it would work until I realized this still has a couple bugs. I didn't realize at first, but javascript's string comparison works left to right. If the first left-most value is greater, then the comparison always returns true, and vice versa. For example:&lt;br&gt;
&lt;code&gt;'10' &amp;gt; '9' ==&amp;gt; false&lt;/code&gt;&lt;br&gt;
&lt;code&gt;'8' &amp;gt; '20' ==&amp;gt; true&lt;/code&gt;&lt;br&gt;
&lt;code&gt;'AA1' &amp;gt; 'B1' ==&amp;gt; false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And remember, column labels in xlsx increment X, Y, Z, AA, AB, AC, etc... Because of this logic, the maxCell function written before wouldn't always work correctly. &lt;/p&gt;

&lt;p&gt;While I'm sure it's possible to modify maxCell() to factor in these constraints, to achieve a working function as desired, but at this point I felt like I was spending too much time on a small feature of my project. There had to be a less involved method to parse the data, or I had to place some constraints on my uploaded xlsx file. &lt;/p&gt;

&lt;p&gt;By limiting the maxColumn to 'Z', I could avoid 'Z' &amp;gt; 'AA'. And then, since the column label is limited to one character, I can convert the row label to an integer and properly compare the row values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function maxCell(cell1, cell2) {
    var row1 = cell1.slice(1)
    var column1 = parseInt(cell1.slice(0,1))
    var row2 = cell2.slice(1)
    var column2 = parseInt(cell2.slice(0,1))

    var maxColumn = (column1 &amp;gt; column2) ? column1 : column 2
    var maxRow = (row1 &amp;gt; row2) ? row1.toString() : row2.toString()

    return `${maxColumn}${maxRow}`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, circling back to the nested for loop I originally wrote, I now have the helper functions to iterate over the xlsx values like originally intended. From here it was easy to format into my database table object and send a POST request.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Active Record Sessions Additional Functionality</title>
      <dc:creator>bperez3237</dc:creator>
      <pubDate>Fri, 29 Jul 2022 20:46:00 +0000</pubDate>
      <link>https://dev.to/bperez3237/active-record-sessions-additional-functionality-5e0l</link>
      <guid>https://dev.to/bperez3237/active-record-sessions-additional-functionality-5e0l</guid>
      <description>&lt;p&gt;For my phase 4 project, my idea was to have a social-media-like app where the user logged in from a specific location. A user's interacting network would be limited to only the location they are logged in from. Because location was part of the login process, the session needed to store location data as well as user data. And then passing this to the client side becomes more difficult since two objects are passed.&lt;/p&gt;

&lt;p&gt;To start from the basics, I setup an auto-login route based on the session. I knew this would need to be a custom route, given my output would need to return user data and location data, so I opted to create a custom controller function instead of the standard show function. My GET route in ruby would be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get '/me', to:'users#auto_login'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And my client side would run a useEffect to fetch this route. Now, if I only needed user data, my auto_login function could be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
def auto_login&lt;br&gt;
     user = User.find_by(id: session[:user_id])&lt;br&gt;
     if user&lt;br&gt;
          render json: user&lt;br&gt;
     else&lt;br&gt;
          render json: { error: 'User not found'}, status: :unauthorized&lt;br&gt;
     end&lt;br&gt;
end&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;How could I get the location of the last session for the auto-login to function? I'm not passing any parameters at the moment... Location is tied to the User through relationships, but this would give me all locations, not the one of the last session. Currently, my function works because I am able to get the user id from the session data. If I stored the location id to session, I could do the same thing. So I go back to my sessions controller create method.&lt;/p&gt;

&lt;p&gt;Nothing too complicated, the same way I stored my user to the session, I will store the location to the session. If the password is authenticated, it will stored the location id from params to session[:location_id]. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
def create&lt;br&gt;
        user = User.find_by(username: params[:username])&lt;br&gt;
        location = Location.find(params[:location_id])&lt;br&gt;
        if user&amp;amp;.authenticate(params[:password])&lt;br&gt;
            session[:user_id] = user.id&lt;br&gt;
            session[:location_id] = location.id&lt;br&gt;
            render json: user, status: :created&lt;br&gt;
        else&lt;br&gt;
            render json: { errors: "Invalid username or password" }, status: :unauthorized&lt;br&gt;
        end&lt;br&gt;
    end&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, going back to my UsersController where I have my auto_login method, I am able to get the session location by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
Location.find_by(id: session[:location_id])&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now I just need to return both objects to the client. I think the cleanest way would be to create a new, nested object, and then render as json. My final auto_login function is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
def auto_login&lt;br&gt;
     user = User.find_by(id: session[:user_id])&lt;br&gt;
     location = Location.find_by(id: session[:location_id])&lt;br&gt;
     if user&lt;br&gt;
          result = {user: user, location: location}&lt;br&gt;
          render json: result&lt;br&gt;
     else&lt;br&gt;
          render json: { error: 'User not found'}, status: :unauthorized&lt;br&gt;
     end&lt;br&gt;
end&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sinatra-React Project Server-Side Cool Features</title>
      <dc:creator>bperez3237</dc:creator>
      <pubDate>Thu, 09 Jun 2022 02:04:30 +0000</pubDate>
      <link>https://dev.to/bperez3237/sinatra-react-project-server-side-cool-features-216o</link>
      <guid>https://dev.to/bperez3237/sinatra-react-project-server-side-cool-features-216o</guid>
      <description>&lt;p&gt;I ran into an interesting issue while working on my Sinatra-react project that opened my eyes to some of the benefits of server side coding.&lt;/p&gt;

&lt;p&gt;Just for some context into my project, my idea was to create a project schedule planner and cost tracker. The user would be able to view the schedule of activities on one page and view all the cost transactions on another page. Each cost belongs to one activity, and each activity has many costs. I wanted the activities to have full CRUD capabilities so someone could change the schedule as things change in the project. The activities have “order” as a parameter so the schedule can sort the activity elements in the correct order.&lt;/p&gt;

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

&lt;p&gt;In creating the “DELETE” request, I realized multiple changes needed to be made to my program for everything to keep making sense. In addition to updating the activities state variable, I would need to update the costs and order of activities. Deleting any activity would change the order of the activities after it. And if I deleted an activity, it would affect any costs with that activity_id. &lt;/p&gt;

&lt;p&gt;Initially I thought to do this with multiple fetch requests. I would complete the "DELETE" request, then do a "GET" for cost and a "GET" for activities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleDelete(id) {
        fetch(`http://localhost:9292/activities/${id}`,{
            method: "DELETE",
        })
        const updatedActivities=activities.filter((activity)=&amp;gt; activity.id !==id)
        setActivities(updatedActivities)
        setToggleInfo(!toggleInfo)

        fetch('http://localhost:9292/costs')
            .then((r)=&amp;gt;r.json())
            .then((data)=&amp;gt;setCosts(data))

        fetch('http://localhost:9292/activities')
            .then((r)=&amp;gt;r.json())
            .then((data)=&amp;gt;setActivities(data))
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This actually isn't too bad considering it seems ridiculous to do in multiple fetch requests. It wasn't until the next day the idea occurred to me to modify the return data from the "DELETE" request, and update the activities and costs on the backend. If I returned a hash from the delete request I could cleanly update both cost and activities states. My code simplified to:&lt;/p&gt;

&lt;p&gt;in ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete '/activities/:id' do
    activity = Activity.find(params[:id])
    activity.costs.each {|cost| cost.destroy}

    start = activity.order - 1
    Activity.all.sort_order[start..].each do |act|
      act.update(order: act.order-1)
    end
    activity.destroy

    res = {'activities': Activity.all, 'costs': Cost.all}
    res.to_json
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleDelete(id) {
        fetch(`http://localhost:9292/activities/${id}`,{
            method: "DELETE",
            headers: {
                'Content-Type': 'application/json'
            }
        })
            .then((r)=&amp;gt;r.json())
            .then((obj)=&amp;gt; {
                setActivities(obj.activities)
                setCosts(obj.costs)
            })
        setToggleInfo(!toggleInfo)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe not a drastic change in number of lines of code, but the logic makes so much more sense now. It then gave me another idea.&lt;/p&gt;

&lt;p&gt;I had completed the "PATCH" request feature a couple days before... and it was a complete mess. &lt;/p&gt;

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

&lt;p&gt;On the server-side, I had essentially nothing. My "PATCH" request would update the order and return the newly update activity object. I would then have to do another "PATCH" to update the order on the activity it was swapping with. All while keeping the state properly updated.&lt;/p&gt;

&lt;p&gt;So, instead of that mess of code, I was going to update the order of both activities from the server side, and then send all the activities so all orders would be kept up to date. Using ActiveRecord, I could make these same changes with less code, and less work updating state on the frontend. I was able to simplify my code to this:&lt;/p&gt;

&lt;p&gt;in ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;patch "/activities/:id" do
    activity = Activity.find(params[:id])
    swap_activity = Activity.find_by(order: params[:order])
    difference = params[:order] - activity.order

    unless params[:order] &amp;lt; 1 || params[:order] &amp;gt; Activity.all.length
      activity.update(order: params[:order])
      swap_activity.update(order: swap_activity.order - difference)
    end
    activities = Activity.all
    activities.to_json
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function handleOrderChange(e, order, id) {
        e.preventDefault()
        const newOrder = parseInt(order)+parseInt(e.target.value)
        fetch(`http://localhost:9292/activities/${id}`, {
            method: "PATCH",
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({order:newOrder}),
        })
            .then((r)=&amp;gt;r.json())
            .then((activities)=&amp;gt; {
                setCurrentActivity(activities.find((activity)=&amp;gt; activity.id===id))
                setActivities(activities)
            })
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Between ruby and js its about half as many lines of code as before! &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Improving Upon My React Application "Postr"</title>
      <dc:creator>bperez3237</dc:creator>
      <pubDate>Fri, 06 May 2022 03:20:23 +0000</pubDate>
      <link>https://dev.to/bperez3237/improving-upon-my-react-application-postr-5d60</link>
      <guid>https://dev.to/bperez3237/improving-upon-my-react-application-postr-5d60</guid>
      <description>&lt;p&gt;Tasked with creating a React application that features client-side routing, I wanted to mimic a typical social media style news feed. As an avid Twitter user, you'll see this is heavily "inspired" by twitter's format.  &lt;/p&gt;

&lt;p&gt;My goal (within the confines and time constraints of this project) was to get down the basic login and post features. Therefore, there are so many possibilities for additional features that could be added.&lt;/p&gt;

&lt;p&gt;Firstly, I wanted to focus on features I could've added given my current skillset. Since I was only required to use GET and POST, I opted not to use PATCH and DELETE requests. My component structure is 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;App
└───Login
or
├───NavBar
└───Home
    └───Post
├───Account
└───UserList
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once simple way to incorporate PATCH and DELETE requests would be like buttons and delete buttons on each individual post. Since I would put these two buttons onto my Post component, I think it makes sense to code these two requests within the Post component. &lt;/p&gt;

&lt;p&gt;In addition to interacting with the server, I need to update my feed state variable in my App and Home components. Given my current destructured props in my Post Component:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WdcagOaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kui8asew5kmkp0n2vv88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WdcagOaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kui8asew5kmkp0n2vv88.png" alt="Image description" width="326" height="261"&gt;&lt;/a&gt;&lt;br&gt;
I would need to add feed and setFeed as props to Post. This would also allow me to add more stats to the Account page such as # of like or # of deletes.&lt;/p&gt;

&lt;p&gt;Currently there is not much info on the Account page, but if this application required a real login, password, email, cell-phone, etc. this would be the location for it. &lt;/p&gt;

&lt;p&gt;Lastly, the third component UserList could be modified to search posts instead of usernames. This is the code for my current UserList component:&lt;/p&gt;

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

&lt;p&gt;It takes in the feed variable from App and uses it to get a non-duplicated array of usernames. I could also switch this to search for posts instead of usernames.&lt;/p&gt;

&lt;p&gt;Simply by switching the conditional in the if statement, i can check the text of the posts (turns out to be easier the way I originally did it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const matchingPosts = feed.map((post)=&amp;gt; {
        if (post.text.includes(search)) {
            return &amp;lt;li key={post.id}&amp;gt;{post.text}&amp;lt;/li&amp;gt;
        }
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could also return a Post component and it might look more like a real application. There could be a toggle for filtering by username or post content. CSS could use some work. Lots and lots of options.&lt;/p&gt;

&lt;p&gt;Theres still endless possibilities this could be taken but I think for now, I'm content with where its at.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Story-time: Tackling No Double Favorite Cat</title>
      <dc:creator>bperez3237</dc:creator>
      <pubDate>Wed, 13 Apr 2022 02:01:20 +0000</pubDate>
      <link>https://dev.to/bperez3237/story-time-tackling-no-double-favorite-cat-56ha</link>
      <guid>https://dev.to/bperez3237/story-time-tackling-no-double-favorite-cat-56ha</guid>
      <description>&lt;p&gt;I wanna talk about a feature I struggled with implementing on my recent project to use a public API to create a single page application.&lt;/p&gt;

&lt;p&gt;So the idea for my project was to create an application to help someone pick their ideal cat to "adopt". The user could search from a list of cat breeds available on the &lt;a href="https://thecatapi.com/"&gt;https://thecatapi.com/&lt;/a&gt;, and the search would return a few bullet points of information. If the user likes a cat, they can "favorite" that breed, and the image and name will be stored in the favorites div while the user searches more cat breeds.&lt;/p&gt;

&lt;p&gt;Before diving into the coding, I thought the difficult part of this project would have been the DOM manipulation combined with the asynchronous behavior of the GET request. But surprisingly... I found myself stuck trying to perfect the "favoriting" feature for a good chunk of time. &lt;/p&gt;

&lt;p&gt;So this is a section of what the basic application looks like after searching a cat breed:&lt;/p&gt;

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

&lt;p&gt;If the favorite button is clicked, a small image with the breed name underneath would appear in the empty favorites div. The only constraints I wanted were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum 3 favorites&lt;/li&gt;
&lt;li&gt;Can't favorite one breed twice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok... easy enough. First I tackled doing maximum 3 favorites. This would be called within a function handling the "favorite!" click event listener. newFavorite is an html div element with the cats image and breed name inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function checkFavorites(newFavorite) {
    const favorites = document.getElementById('favorites')

    if (favorites.children.length === 3) {
        favorites.removeChild(favorites.children[0])
        favorites.appendChild(newFavorite)
    }
    else {
        favorites.appendChild(newFavorite)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I test ran it, and it worked fine. Simple, great! Ok-- next part.&lt;/p&gt;

&lt;p&gt;The first problem I had: how was I going to check if the newFavorite cat breed I was passing into my function was already favorited? The favorites are all added into the "favorites" div using appendChild(newFavorite). This is the HTML after one cat breed is added to favorites: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r8_DLdfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ruveoqwu3sh26hn7hsh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r8_DLdfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ruveoqwu3sh26hn7hsh1.png" alt="HTML Snippet" width="352" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I could check all the children of the "favorites" div element. Probably easiest to iterate through favorites.children and check if the breed name in newFavorites matches a child of favorites. If I was to code this by itself, without the 3 cat limit, this is what I came up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function checkFavorites(newFavorite) {
    const favorites = document.getElementById('favorites')
    const currentBreedName = newFavorite.getElementsByTagName('p')[0].textContent

    let checker = true
    for (i=0;i &amp;lt; favorites.children.length ;i++) {
        if (favorites.children[i].getElementsByTagName('p')[0].textContent === currentBreedName) {
            checker = false
        }
    }

    if (checker === true) {
        favorites.appendChild(newFavorite)
    }
    else {
        alert('AREADY IN FAVORITES')
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The for loop iterates through all the current children of favorites and uses an if statement to check if the name matches the one I am trying to add. I can't use appendChild within my for loop, or else I could append more than once. So I create a 'checker' variable and use a second if statement to action the appendChild after the for loop is done.&lt;/p&gt;

&lt;p&gt;Took me a little bit to figure that one out, but sure enough, this code works by itself. Next step would be to combine it with the code I made to limit to 3 favorites. If combined in the right order, this should work right?&lt;/p&gt;

&lt;p&gt;I'm not exactly sure why I decided to cap it at 3 cats or even at all. Maybe to help the user with decision paralysis or make it aesthetically pleasing or... Anyways...&lt;/p&gt;

&lt;p&gt;If I copy paste my first code block and put it right after my second code block... it doesn't work. If you favorite the same breed twice, it will alert you it is "ALREADY IN FAVORITES", but when it passes the second code block, since it hasn't reached 3 children, it appends the double-favorited cat.&lt;/p&gt;

&lt;p&gt;And vice versa: if I order the two code blocks the other way, I get the same behavior. So still not working. Maybe if I put code block 1 in the middle of code block 2? Code block 1 inside the for loop of code block 2? A nested if statement within a for loop within an if statement???&lt;/p&gt;

&lt;p&gt;I wasn't expecting this to stump me but I was little low on morale at the time. Maybe I should change my constraints to make the coding easier?&lt;/p&gt;

&lt;p&gt;Somehow-- it eventually came to me. If I combined the two if statements using &amp;amp;&amp;amp;, I could get the elements appended/removed in the right order to get the behavior I was looking for. And much easier to read than some of the other options I was thinking of trying.&lt;/p&gt;

&lt;p&gt;This is the final version of the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function checkFavorites(newFavorite) {
    let favorites = document.getElementById('favorites')
    let currentBreedName = newFavorite.getElementsByTagName('p')[0].textContent

    let checker = true
    for (i=0; i &amp;lt; favorites.children.length ;i++) {
        if (favorites.children[i].getElementsByTagName('p')[0].textContent === currentBreedName) {
            checker = false
        }
    }
    if (favorites.children.length != 3 &amp;amp;&amp;amp; checker === true) {
        favorites.appendChild(newFavorite)
    }
    else if (favorites.children.length === 3 &amp;amp;&amp;amp; checker === true) {
        favorites.removeChild(favs.children[0])
        favorites.appendChild(newFavorite)
    }
    else {
        alert('AREADY IN FAVORITES')
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining (favorites.children.length != 3) boolean with (checker === true) allows me to appendChild only once, and making sure I am following both my constraints at once. Alternatively, I could have done the same thing with else if statements, but I think it would have affected the readability.&lt;/p&gt;

&lt;p&gt;Simple enough-- I thought. Anyone have a better solution?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
  </channel>
</rss>
