<?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: Julie Evans</title>
    <description>The latest articles on DEV Community by Julie Evans (@mailauki).</description>
    <link>https://dev.to/mailauki</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%2F733826%2Fac6b7ce4-9b5c-4b8b-9f9b-8d989e1bd720.jpeg</url>
      <title>DEV Community: Julie Evans</title>
      <link>https://dev.to/mailauki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mailauki"/>
    <language>en</language>
    <item>
      <title>Fetching in Tandem</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Wed, 31 Aug 2022 21:36:48 +0000</pubDate>
      <link>https://dev.to/mailauki/fetching-in-tandem-20o9</link>
      <guid>https://dev.to/mailauki/fetching-in-tandem-20o9</guid>
      <description>&lt;p&gt;To start off let me first explain what I mean by fetching in tandem. Fetching is a process to access the data from a database or API with a &lt;em&gt;fetch request&lt;/em&gt;. More about fetching can be found &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch"&gt;here&lt;/a&gt;. To have this process run in duality is what I mean for it to be in tandem. That is if I make a fetch request that requires either the data from another fetch request or at least the process to have run. In this particular case, I wanted to have a fetch request nested inside another, so that it would run right after the other within a single motion. So it’s not exactly simultaneous but in my case I had it run in a single handler function, so I consider that to be a single motion and thus in tandem.&lt;/p&gt;

&lt;p&gt;Now to explain what I had going on in this example and how I got to that point, I will first explain my setup. My database was set up with a many-to-many relationship pertaining to three tables. These tables were a Photos table, a Tags table, and a PhotoTags table. The PhotoTags table is the join-table connecting the other two, with a foreign key column for each of the other respective tables.&lt;/p&gt;

&lt;p&gt;For some reference here is what my schema looks like:&lt;/p&gt;

&lt;h6&gt;
  
  
  db/schema.rb
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s"&gt;"photos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;force&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="s"&gt;"image"&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"description"&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="s"&gt;"user_id"&lt;/span&gt;
&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;force&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;
&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;create_table&lt;/span&gt; &lt;span class="s"&gt;"photo_tags"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;force&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;cascade&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="s"&gt;"photo_id"&lt;/span&gt;
  &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="s"&gt;"tag_id"&lt;/span&gt;
&lt;span class="n"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Going forward I will explain what I had going on. To start with this example involves a form page set up to add photos to the database. This form has three inputs: Image, Description, and Tags. Image is for the image URL. Description and Tags are optional. Description is for if the &lt;em&gt;user&lt;/em&gt; wants to add some descriptive text to the &lt;em&gt;photo&lt;/em&gt;. Tags is for adding and selecting &lt;em&gt;tags&lt;/em&gt; from the database in order to have them attached to the &lt;em&gt;photo&lt;/em&gt;. Adding &lt;em&gt;tags&lt;/em&gt; to the database is handled by an &lt;code&gt;onKeyDown&lt;/code&gt; event handler function, but more importantly, attaching those &lt;em&gt;tags&lt;/em&gt; is handled by an &lt;code&gt;onChange&lt;/code&gt; event handler function for selecting and then a POST fetch request for attaching them to the &lt;em&gt;photo&lt;/em&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  client/AddPhoto.js: onChange
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;setSelectedTags&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;selectedTags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;setSelectedTags&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my &lt;code&gt;onChange&lt;/code&gt; handler for the &lt;em&gt;tags'&lt;/em&gt; form input. Simply put, I check to see if there are any &lt;em&gt;tags&lt;/em&gt; in the input and add them to a state variable called &lt;code&gt;selectedTags&lt;/code&gt;. I checked if there was a &lt;em&gt;tag&lt;/em&gt; added by seeing if the &lt;code&gt;newValue&lt;/code&gt; prop was empty or not. I then matched the &lt;code&gt;newValue&lt;/code&gt; with the &lt;code&gt;tags&lt;/code&gt; from the database. Both &lt;code&gt;tags&lt;/code&gt; and &lt;code&gt;newValue&lt;/code&gt; are arrays, but the &lt;code&gt;tags&lt;/code&gt; array is from the database and thus has &lt;em&gt;id&lt;/em&gt;'s where as the &lt;code&gt;newValue&lt;/code&gt; array only has the &lt;em&gt;name&lt;/em&gt; value of the &lt;em&gt;tag&lt;/em&gt;. I match these two arrays by filtering through both. I do this in order to grab the &lt;em&gt;tag&lt;/em&gt; from the database that has the same &lt;em&gt;name&lt;/em&gt; as the &lt;em&gt;tag&lt;/em&gt; in the &lt;code&gt;newValue&lt;/code&gt; array. Basically, I'm grabbing the &lt;em&gt;tag&lt;/em&gt; with its &lt;em&gt;id&lt;/em&gt; from the array displayed on the DOM. If they do match the comparison I set them to the &lt;code&gt;selectedTags&lt;/code&gt; array using &lt;code&gt;useState&lt;/code&gt;. This way the &lt;code&gt;selectedTags&lt;/code&gt; array matches what the user sees on the DOM but also contains the &lt;em&gt;id&lt;/em&gt;'s to help later with adding the association to the photo via the &lt;code&gt;photo_tags&lt;/code&gt; Join table.&lt;/p&gt;

&lt;p&gt;The harder part is adding that association, taking the &lt;em&gt;tags&lt;/em&gt; that have been selected and attaching them to the &lt;em&gt;photo&lt;/em&gt;. To do this requires a &lt;strong&gt;POST fetch request&lt;/strong&gt; to the &lt;code&gt;photo_tags&lt;/code&gt; Join table, for each &lt;em&gt;tag&lt;/em&gt; to be attached to the &lt;em&gt;photo&lt;/em&gt;. But first, we need to have &lt;em&gt;photo&lt;/em&gt; to add these to. That isn't really a problem, except that the &lt;em&gt;photo&lt;/em&gt; needs to be in the database and have an &lt;em&gt;id&lt;/em&gt;. This is because the association between the &lt;em&gt;photos&lt;/em&gt; and &lt;em&gt;tags&lt;/em&gt; in the Join table are reliant on &lt;em&gt;id&lt;/em&gt;'s as its foreign keys (look to the schema for clarification on this). This isn't a problem either, because I just need to run a POST fetch request to add the &lt;em&gt;photo&lt;/em&gt; to the database and then run the POST fetch request to the Join table to attach the &lt;em&gt;tags&lt;/em&gt;. The problem here lies in the fact that this is one form with one submit button. So in order to have the &lt;em&gt;tags&lt;/em&gt; associated with the &lt;em&gt;photo&lt;/em&gt; as well as the &lt;em&gt;photo&lt;/em&gt; to be added to the database upon clicking the single submit button I need to run both POST fetch requests almost simultaneously. I do this by running the two fetch requests right after each other inside the submit handler function. This way they both initiate upon the submit button click, but I also control them so that the &lt;em&gt;photo&lt;/em&gt;'s fetch request is run and with the return of the data from its completion to then run the &lt;code&gt;photo_tag&lt;/code&gt;'s fetch request with that data.&lt;/p&gt;

&lt;p&gt;Here is what my submit handler function looks like:&lt;/p&gt;

&lt;h6&gt;
  
  
  client/AddPhoto.js: handleSubmit
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

 &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/photos"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="nv"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;
   &lt;span class="p"&gt;},&lt;/span&gt;
   &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;
 &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedTags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="n"&gt;selectedTags&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/photo_tags"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="nv"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;
             &lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nv"&gt;photo_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;tag_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
           &lt;span class="p"&gt;})&lt;/span&gt;
           &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;photoTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;photoTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;})&lt;/span&gt;
             &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
             &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;})&lt;/span&gt;
         &lt;span class="p"&gt;})&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;currentUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nf"&gt;setErrors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The formData here is an object that contains the URL of the &lt;em&gt;image&lt;/em&gt; and the &lt;em&gt;description&lt;/em&gt; for the &lt;em&gt;photo&lt;/em&gt;. These are added via &lt;code&gt;useState&lt;/code&gt; from the other form inputs. I have errors set from both fetch requests, but since the &lt;code&gt;photo_tag&lt;/code&gt; fetch request can't run without the &lt;em&gt;photo&lt;/em&gt;'s &lt;em&gt;id&lt;/em&gt; or the &lt;em&gt;tags&lt;/em&gt;' &lt;em&gt;id&lt;/em&gt;'s it never gets to that point. I also console logged the data from the &lt;code&gt;photo_tag&lt;/code&gt; fetch request to confirm everything's working properly. I set the &lt;code&gt;photo_tag&lt;/code&gt; fetch request to run after the &lt;em&gt;photo&lt;/em&gt; fetch request by nesting it inside of its response, and it also will only run if &lt;em&gt;tags&lt;/em&gt; have been selected (since adding &lt;em&gt;tags&lt;/em&gt; to a &lt;em&gt;photo&lt;/em&gt; is optional). If there are &lt;code&gt;selectedTags&lt;/code&gt; it will iterate through them and run the &lt;code&gt;photo_tag&lt;/code&gt; fetch request for each &lt;em&gt;tag&lt;/em&gt;. Once all of the fetch requests have run it will then redirect to the user's page I have set up with the &lt;em&gt;id&lt;/em&gt; of the &lt;em&gt;user&lt;/em&gt; that is logged in (aka. the &lt;code&gt;currentUser&lt;/code&gt;). On a side note, the addition of &lt;em&gt;photos&lt;/em&gt; and &lt;em&gt;tags&lt;/em&gt; also requires a &lt;em&gt;user&lt;/em&gt; to be logged in. The &lt;code&gt;photo&lt;/code&gt; table also has a &lt;code&gt;user_id&lt;/code&gt; foreign key, but that is handled in the controller, here:&lt;/p&gt;

&lt;h6&gt;
  
  
  app/controllers/photos_controller.rb: create
&lt;/h6&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
  &lt;span class="n"&gt;photo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;@current_user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;photos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;photo_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="nv"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;created&lt;/span&gt;
&lt;span class="n"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In conclusion, it is not that I have fetches running simultaneously, but that I have them run one after the other by nesting them and having them within a single action (submit handler initiated upon button click action).&lt;/p&gt;

</description>
      <category>react</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Creating a “Follow” button: from Rails to React using Self-Join</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Wed, 15 Jun 2022 23:02:04 +0000</pubDate>
      <link>https://dev.to/mailauki/creating-a-follow-button-from-rails-to-react-using-self-join-jc2</link>
      <guid>https://dev.to/mailauki/creating-a-follow-button-from-rails-to-react-using-self-join-jc2</guid>
      <description>&lt;p&gt;For the first time, I attempted creating a button that a user could click to &lt;em&gt;follow&lt;/em&gt; or &lt;em&gt;unfollow&lt;/em&gt; another user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database and Self-Join
&lt;/h3&gt;

&lt;p&gt;First of all, the database is set up as a many-to-many relationship. But, it is also self-referential, otherwise known as a self-join. This means that the data in the database uses another table (in this case “Friendship”) to reference a table with itself (in this case “User”). More on this later… &lt;/p&gt;

&lt;p&gt;Here is the schema and a diagram to demonstrate these database tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// db/schema.rb

  create_table "friendships", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "follower_id"
    t.integer "followee_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fh8sozu05wr5ask6x4oiz.jpeg" 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%2Fh8sozu05wr5ask6x4oiz.jpeg" alt="Database table chart"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reading &lt;a href="https://medium.com/@ingridf/the-power-of-self-referential-associations-in-rails-and-self-joins-a9d31b181e4" rel="noopener noreferrer"&gt;this&lt;/a&gt; and &lt;a href="https://medium.com/@TheDickWard/self-referential-relationships-aka-self-joins-in-rails-64f8f36ac311" rel="noopener noreferrer"&gt;this&lt;/a&gt;, in addition to the &lt;a href="https://guides.rubyonrails.org/association_basics.html#self-joins" rel="noopener noreferrer"&gt;Rails guide&lt;/a&gt;, I got an understanding of Self-Join. In the case I used it, based on this, the database needs to be set up just like a many-to-many relationship. It needs a separate table to act as a go-between and store the action’s information. The only difference would be that instead of this separate table in between &lt;em&gt;two&lt;/em&gt; other tables, it would have &lt;em&gt;one&lt;/em&gt; other table referencing itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;User &amp;gt;- Friendship -&amp;lt; User&lt;/em&gt;&lt;br&gt;
(the &lt;em&gt;User&lt;/em&gt; here is the same table - just the connection would look like this)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;instead of something like this…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;User &amp;gt;- Like -&amp;lt; Post&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another way to look at it is that the Friendship table holds the information pertaining to the “follow” action in this case, and that info contains the id of the user that initiated the action as a foreign key as well as the id of the user the action was initiated upon also as a foreign key. It has two user ids, one in the follower column and the other in the followee column.&lt;/p&gt;

&lt;p&gt;The Friendship database table would look something like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;follower_id&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;followee_id&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: For clarification, the first row has the user with the id of 1 following the user with the id of 2,  and the second row has the user with the id of 1 being followed by the user with the id of 2. Also, the ids of the users are the primary keys from the User table. On a side note, this table would also have another column for the primary key of the relationship or row in the Friendship table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Rails Backend
&lt;/h3&gt;

&lt;p&gt;On the back-end of things, there are primarily two things, the models and the controllers concerning this Friendship table as well as the User table.&lt;/p&gt;

&lt;p&gt;The most important part of this whole thing lies in the models, especially the &lt;em&gt;User&lt;/em&gt; model. Both of these models set up the connections for the tables in the database. The &lt;em&gt;Friendship&lt;/em&gt; model essentially allows the &lt;code&gt;follower&lt;/code&gt; and &lt;code&gt;followee&lt;/code&gt; to be present and that they come from the &lt;em&gt;User&lt;/em&gt; model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/models/friendship.rb

class Friendship &amp;lt; ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followee, class_name: "User"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The User model is a bit more complicated. It needs the send the &lt;code&gt;follower&lt;/code&gt; and &lt;code&gt;followee&lt;/code&gt; to the &lt;em&gt;Friendship&lt;/em&gt; model. In order to do that it needs to define them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/models/user.rb

class User &amp;lt; ApplicationRecord
  has_many :followed_users, foreign_key: :follower_id, class_name: "Friendship"
  has_many :followees, through: :followed_users
  has_many :following_users, foreign_key: :followee_id, class_name: "Friendship"
  has_many :followers, through: :following_users
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;followers&lt;/code&gt; and &lt;code&gt;followees&lt;/code&gt; are the same as the &lt;code&gt;follower&lt;/code&gt; and &lt;code&gt;followee&lt;/code&gt; from the Friendship model. They are defined using &lt;code&gt;has_many, through:&lt;/code&gt;. The key that it is &lt;em&gt;through&lt;/em&gt; here is from another &lt;code&gt;has_many&lt;/code&gt; which is defined using &lt;code&gt;foreign_key:&lt;/code&gt;. This foreign key is the key used to define the column in the Friendship table from the database, which were &lt;code&gt;follower_id&lt;/code&gt; and &lt;code&gt;followee_id&lt;/code&gt;. These are from the Friendship &lt;em&gt;table&lt;/em&gt; and are the foreign keys that are defined clearly in the model here with the &lt;code&gt;has_many&lt;/code&gt; statement. The &lt;code&gt;has_many, through:&lt;/code&gt; statements are simply to allow access to these foreign keys in the Friendship model under new labels for clarity.&lt;/p&gt;

&lt;p&gt;The controllers define the actions of the models. Here the Friendship controller is the more important one. It defines the adding and deleting of data to the Friendship table, or in other words the creation and deletion of new rows in the table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/controllers/friendships_controller.rb

class FriendshipsController &amp;lt; ApplicationController

  def create
    friendship = Friendship.create!(friendship_params)
    render json: friendship, status: :created
  end

  def destroy
    friendship = Friendship.find_by!({follower_id: session[:user_id], followee_id: params[:id]})
    friendship.destroy
    head :no_content
  end

  private

  def friendship_params
    params.permit(:id, :followee_id, :follower_id)
  end

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

&lt;/div&gt;



&lt;p&gt;In the methods defined here, the Friendship class must be used to define the action. If the action is defined using the User class (ex. User.followers.create!) the action of this method will most likely trigger the creation or deletion of new users, rather than the creation or deletion of a relationship between them (aka. a following or unfollowing).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: Using &lt;code&gt;User.followers&lt;/code&gt; or &lt;code&gt;User.followees&lt;/code&gt; will work in the console will the shovel method. Look at &lt;a href="https://medium.com/@TheDickWard/self-referential-relationships-aka-self-joins-in-rails-64f8f36ac311" rel="noopener noreferrer"&gt;this&lt;/a&gt; for more information or examples on this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, the parameters or params used are the foreign keys directly from the table rather than the new labels from the model. In addition, the params used for the delete method use the user id saved in the session since this action can only be performed when there is a user logged in anyways, and the other params are from the fetch request route that has the &lt;code&gt;:id&lt;/code&gt; of the user being followed. The delete here grabs both of these in an object as the &lt;code&gt;follower_id&lt;/code&gt; and &lt;code&gt;followee_id&lt;/code&gt; respectively. This is so the &lt;code&gt;find_by&lt;/code&gt; will target the &lt;em&gt;whole row&lt;/em&gt; in the Friendship table that has the &lt;em&gt;exact same&lt;/em&gt; information.&lt;/p&gt;

&lt;p&gt;The creation method is similar, except that this object is defined in the body of the fetch request instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Frontend
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// client/src/components/FollowBtn.js

function FollowBtn({currentUser, user, onError, onFollow, isFollowing}) {

  function handleFollow(e) {
    const following = currentUser ? {followee_id: user.id, follower_id: currentUser.id} : null

    isFollowing ? (
      fetch(`/friendships/${user.id}`, {
        method: "DELETE",
        headers: {
          "Content-Type": "application/json",
        }
      })
        .then((r) =&amp;gt; {
          onFollow(false)
        })
      ) : (
        fetch("/friendships", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(following)
        })
          .then((r) =&amp;gt; {
            if (r.ok) {
              r.json().then((data) =&amp;gt; {
                onFollow(true)
              })
            } else {
              r.json().then((err) =&amp;gt; onError(err.errors))
            }
          })
      )
  }

  return(
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={handleFollow} className="button"&amp;gt;{isFollowing ? "Unfollow" : "Follow"}&amp;lt;/button&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

export default FollowBtn;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a lot, but this is the component for the &lt;em&gt;Follow&lt;/em&gt; button that includes the function on the front-end that handles the clicking of the button.&lt;/p&gt;

&lt;p&gt;It takes the &lt;code&gt;currentUser&lt;/code&gt; and user variables from its parent. The &lt;code&gt;currentUser&lt;/code&gt; is the variable fetched from the user saved in the &lt;em&gt;session&lt;/em&gt;, in other words, whoever is logged in on the browser. The &lt;code&gt;user&lt;/code&gt; is from the data that the button is set on, which also makes it whoever the &lt;em&gt;follow&lt;/em&gt; is attached to or the one to be followed. If there is a current user or a user logged in, the &lt;code&gt;following&lt;/code&gt; variable is an object containing the id of the user as the &lt;code&gt;followee_id&lt;/code&gt; and the id of the current user as the &lt;code&gt;follower_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;following&lt;/code&gt; variable is the object for the body of the fetch request. The &lt;code&gt;isFollowing&lt;/code&gt; variable is a boolean that checks to see if the current user is already following this user. If they are already following them, then the click on the button will go to the DELETE fetch request, otherwise it will go to the POST fetch request. The DELETE fetch sends the request to the &lt;code&gt;/:id/unfollow&lt;/code&gt; route I have defined, but this requires the id of the user that this button is attached to. The POST fetch does not require the id because it is in the body of the request.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;onFollow&lt;/code&gt; sends the data of these actions to the parent, which controls the &lt;code&gt;isFollowing&lt;/code&gt; variable as well as whether the button displays “FOLLOW” or “UNFOLLOW”. The &lt;code&gt;onError&lt;/code&gt; similarly sends data to the parent, but it only sends the /errors/ if there are any. This was simply for display convenience, because it looked better in the parent rather than inside the button itself 😅.&lt;/p&gt;

&lt;h3&gt;
  
  
  For more references:
&lt;/h3&gt;

&lt;p&gt;These are some articles I found on this topic, or at least a part of or similar topics. Mostly revolving around self-join (since this was uncharted territory for me).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@TheDickWard/rails-relationships-a-user-by-any-other-name-c6c9f0adc972" rel="noopener noreferrer"&gt;https://medium.com/@TheDickWard/rails-relationships-a-user-by-any-other-name-c6c9f0adc972&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/full-taxx/how-to-add-likes-to-posts-in-rails-e81430101bc2" rel="noopener noreferrer"&gt;https://medium.com/full-taxx/how-to-add-likes-to-posts-in-rails-e81430101bc2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@klee.mcintosh/setting-up-a-self-join-with-rails-activerecord-9137062fac8b" rel="noopener noreferrer"&gt;https://medium.com/@klee.mcintosh/setting-up-a-self-join-with-rails-activerecord-9137062fac8b&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kartikey.dev/2020/09/29/many-to-many-self-joins-in-rails.html" rel="noopener noreferrer"&gt;https://www.kartikey.dev/2020/09/29/many-to-many-self-joins-in-rails.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/25493368/many-to-many-self-join-in-rails" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/25493368/many-to-many-self-join-in-rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@asuthamm/self-join-in-rails-8e3fc99c0634" rel="noopener noreferrer"&gt;https://medium.com/@asuthamm/self-join-in-rails-8e3fc99c0634&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flatironschool.com/blog/self-referential-associations-aka-self-joins/" rel="noopener noreferrer"&gt;https://flatironschool.com/blog/self-referential-associations-aka-self-joins/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tmtarpinian.com/self-joins-in-rails/" rel="noopener noreferrer"&gt;https://tmtarpinian.com/self-joins-in-rails/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://betterprogramming.pub/building-self-joins-and-triple-joins-in-ruby-on-rails-455701bf3fa7" rel="noopener noreferrer"&gt;https://betterprogramming.pub/building-self-joins-and-triple-joins-in-ruby-on-rails-455701bf3fa7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>rails</category>
      <category>react</category>
      <category>database</category>
    </item>
    <item>
      <title>CSS Components</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Sat, 26 Mar 2022 00:50:18 +0000</pubDate>
      <link>https://dev.to/mailauki/css-components-3h4g</link>
      <guid>https://dev.to/mailauki/css-components-3h4g</guid>
      <description>&lt;p&gt;When I was first introduced to React and it’s components, I fell in love with them. I couldn't believe I didn't know about them or even anything like them until that point. Also to note, I'm an avid folders user in organizing my computer content, especially photos. So its understandable how excited I got when I found I could do the same for my code.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In case you don't know what components are... A good explanation is here on &lt;a href="https://reactjs.org/docs/components-and-props.html"&gt;React docs on Components and Props&lt;/a&gt;. For me, I would describe components as good way to compartmentalize your code. I like to imagine components as Lego blocks or comparable to folders. Like building blocks or parts to use, reuse, and build off of as well as to organize. Although I think that the construction and utilization of components is nearly identical to that of functions.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One day, I thought to myself, “why don't I apply components to my CSS.” Although I was utilizing the components in React to reuse and compartmentalize my code, I still had an insanely long and convoluted CSS file. So, when I had this idea I thought I’d try it out with my next project. Which, considering how much I liked components and organizing stuff, I surprised myself with that it took me this long.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since I was styling based on parts, my CSS file would be in segments based on those. Although my CSS file was somewhat organized, but despite this, I can bet that I am probably the only one that could understand it, and see where things were and what was going on.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To say the least, applying components to CSS was a great success. Not only could I compartmentalize and organize my styles, but also easily know which React components they were connected to because I also based my CSS components off of my React components.&lt;/p&gt;

&lt;p&gt;It helped me the most where I styled a form. The project I tried using Css components on had four different submission forms and three different styles of those forms. I reused the CSS just as I would have for React components.&lt;/p&gt;

&lt;p&gt;I started by creating one CSS component as a generalized or base style, which I mainly used to keep colors consistent, set direction flow, and to set the minimum size. After that I made new CSS components for each other different type of form. I had one form be a larger version and another be horizontal instead of vertical.&lt;/p&gt;

&lt;p&gt;Since I had the generalized form CSS component, I didn't have to do much for the third type, where as the other 2 simply played off of the generalized style. I only changed the parts that needed to be different for the other two types of form styles, and everything else stayed the same which stayed in the base styles component. Not only did this all simplify my CSS code, but it also made it easier to look at and compare.&lt;/p&gt;

&lt;p&gt;Although I could talk in more detail about this and how good it is, I will stop here. The main take away from all of this is that compartmentalizing code makes looking at and using code so much better, especially for reuse and comparison, and the best part is that its even better with CSS.&lt;/p&gt;

&lt;p&gt;One last thing to note, I’ve referred to these as CSS components but it might be better to describe them closer to separated CSS files or folder-like CSS segments. React components are individual files that act like functions, but the CSS components here are individual files of ordinary CSS that I organized to match my React components. So I call them components based on how I synchronized them with my React components rather than by pure definition.&lt;/p&gt;

</description>
      <category>css</category>
      <category>react</category>
    </item>
    <item>
      <title>Communication between Sinatra Routes and React Fetch Requests</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Sat, 26 Mar 2022 00:48:57 +0000</pubDate>
      <link>https://dev.to/mailauki/communication-between-sinatra-routes-and-react-fetch-requests-4cmb</link>
      <guid>https://dev.to/mailauki/communication-between-sinatra-routes-and-react-fetch-requests-4cmb</guid>
      <description>&lt;h3&gt;
  
  
  What are Routes and Requests anyways?
&lt;/h3&gt;

&lt;p&gt;For those who don’t know what Sinatra routes or React fetch requests are, I’ll give a brief rundown. Sinatra routes are the communication between you and the database, and function similarly to URLs. React fetch requests are a way for React to communicate with a backend like an API or database, and in this case using the Sinatra routes as a medium or mediator.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is this all about?
&lt;/h3&gt;

&lt;p&gt;Although this title is pretty long, it sums up all that I plan to say. First I'd like to say that this was an issue I came across, and it took me awhile to figure out what the problem was. I struggled with it because I had assumed my mistake was on my frontend, like a typo or something. I thought this because of how complicated the part I was working on was. It was my EDIT button, and I had the data traveling through several components back and forth, as well as through different functions and nested if statements.&lt;/p&gt;

&lt;p&gt;To figure out that it was not my frontend that had the error, I turned off the data being sent so that I was left with just the components. I went through each step that the data would travel through, and checked what it was with a console.log. In doing this I saw that it was not my complicated traveling or nested if statements. The problem lied in the data itself, or to be more accurate what happened to the data as it travel.&lt;/p&gt;

&lt;p&gt;While I logged the data at each step, I noticed a discrepancy. The data I sent to be edited and the data sent back after being edited were different. I was a slight difference and a small mistake on my part, so I simply didn't notice it. In fact, I hadn't noticed it until it was breaking my code.&lt;/p&gt;

&lt;p&gt;The mistake was in my databases, or more specifically my routes. I had my Sinatra routes looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;patch&lt;/span&gt; &lt;span class="s2"&gt;"/items/:id"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;price: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;priority: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:priority&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;category: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;balance_id: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:balance_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the route like this, the data received afterwards would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;balance_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem was that my data being sent to it looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.00&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what was happening was that the data I sent to be edited had a "balance" key, whereas the edited data I got back had a "balance_id". My code was breaking because when I tried to render the new data it would try to read the keys of the object under the "balance" key, but it no longer existed.&lt;/p&gt;

&lt;p&gt;It all had to do with what my Sinatra routes gave and received, but my databases and how my data was connected between them also played a part. To explain I'll first explain what my databases and data was doing on the backend. To start the data in my databases and how they were connected could be best shown with this diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bzEMcQFN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jd46chc4r3uqbr01tlgb.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzEMcQFN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jd46chc4r3uqbr01tlgb.jpeg" alt="diagram" width="484" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had a one-to-many relationship between my balances and items databases, with a foreign id connecting them. This was all fine and good up until I was writing my routes. Having my routes have the "balance_id" key was not the problem, since that was the connecting factor. Because I was working with items I needed the keys to match the columns on the database, which I did. The problem was that my other routes had the data shown differently that how it was received. I needed the data received to be consistent throughout all of my routes.&lt;/p&gt;

&lt;p&gt;The fix was simple, since &lt;em&gt;how&lt;/em&gt; I was sending my data was not the issue. I simply needed to add the same statement specifying how I want the data to look, or in other words what the data received was. Which was the "only" and "includes" I had added to the other routes, but had forgotten to add here. The fixed version of my Sinatra route looked liked this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;patch&lt;/span&gt; &lt;span class="s2"&gt;"/items/:id"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;price: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;priority: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:priority&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;category: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;balance_id: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:balance_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:priority&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:category&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;include: :balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the data in essence was the same, how it looked and communicated between the frontend and backend was different. I found this subtle difference fascinating, and could apparently make-or-break my code. What was even more interesting was that my fetch request in React looked the same as the database, the same as the routes. It looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;itemName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;itemPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;itemPriority&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;itemCategory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;balance_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;balanceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`http://localhost:9292/items/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PATCH&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;onEditSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "formData" here in the fetch request and the part inside of the update in the route are exactly the same. They need to be identical in order to work with database, where they need to match the columns. These parts need to be identical to function. But since I had the balances database attached to the items and an add on, neither the data nor the databases changed, simply the way it looked afterwards.&lt;/p&gt;

&lt;p&gt;Both the fetch requests and routes communicate with each other and the databases the same way. I simply told it to show me the balance connect to the item instead of the foreign id, which was all in the only and includes attached to the "to_json" on the routes. The "only part specified what keys to display. And the "includes" told it to include the whole balance (instance) connected, since I could do that with how my databases were set up. The fetch request on the other end communicates with the databases with the routes as mediators, so without specifying what to display with these "only" and "includes" statements the data would look identical to the default or simply the database itself.&lt;/p&gt;

&lt;p&gt;So the takeaway is that the data sent needs to be identical regardless if it is in the route, fetch request, or the database. The only thing is that if you specify how the data received looks, you must be consistent.&lt;/p&gt;

</description>
      <category>react</category>
      <category>ruby</category>
      <category>database</category>
    </item>
    <item>
      <title>Reflecting on React</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Sun, 06 Feb 2022 23:13:39 +0000</pubDate>
      <link>https://dev.to/mailauki/reflecting-on-react-511h</link>
      <guid>https://dev.to/mailauki/reflecting-on-react-511h</guid>
      <description>&lt;p&gt;During this past month or so I learned how to utilize React. Although I only learned the basics and can only make good use of two hooks, I can implement them in ways to make them work. I can also utilize JSX and React’s hooks to implement the same functionality as if I were using JavaScript. The primary different is the ease of use and the lack of complexity in the appearance. My favorite aspect of using JSX instead of simply using JavaScript, is that JSX looks similar to typical HTML and makes it easier to see what is going on in the code. Plus I can implement the JavaScript functionality directly into the same code I use for rendering. So for me it’s like looking at HTML that functions as JavaScript, which is both beautiful and easier to use, at least it is for me. &lt;/p&gt;

&lt;p&gt;Other than how much better I like JSX in comparison to typical JavaScript, is the use of React, which is super great. I can use it to render the HTML by using JSX and use its hooks to store information and the like and minimize unnecessary extra loading or rendering. I really like using the useState hook, because it not only makes my life easier with it storing information, it is also really easy to use. I previously used simple variables in JavaScript to achieve the same functionality, but it was messy and complicated, and it just barely helped me to achieve the functionality I wanted. Looking back I probably overcomplicated my situation more than necessary, but regardless using useState is much kinder to me. Using the useState hook not only is simple to use, but is also not a strain to look at and can be used without much complexity. &lt;/p&gt;

&lt;p&gt;In addition to the useState hook I learned to utilize the useEffect hook, which I primarily used in tandem with useState. This was to fetch data from an API or JSON file and store the data within a variable declared with useState and then be able to utilize that data with ease without extraneous fetch requests. The useEffect hook has other neat uses and side-effects that can be implemented here and there, but I found its use with fetch requests was very helpful and made things easier to look at and more organized for me to use. If you can find at least one use for it and be able to utilize it, then I think that is enough to get by. &lt;/p&gt;

&lt;p&gt;I primarily used the useState and useEffect hooks, but I also learned about routing with “react-router-dom” and using its hooks. It’s extremely helpful and quicker using this routing, and the uses it has in addition to simple links make creating navigation bars and alternating page content super simple. In addition to React’s hooks and features that can be accessed and used by simply importing them, there are other features and the like that are just as easy to get a hold of and use. Rather than trying to learn how to accomplish something and straining to figure out the ins and out of a certain feature, you can simply import the feature itself. Working with features and components this way makes creating content and features so much simpler and quicker. Utilizing React and similar features is the coolest thing I have come across so far, and using it through JSX is a joy to look at and use. The combination of the two is a wonder to behold and an ease to use. &lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>currentTarget vs. target</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Fri, 31 Dec 2021 02:49:11 +0000</pubDate>
      <link>https://dev.to/mailauki/currenttarget-vs-target-3427</link>
      <guid>https://dev.to/mailauki/currenttarget-vs-target-3427</guid>
      <description>&lt;p&gt;One of the things I have learned recently is the difference between &lt;code&gt;currentTarget&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt;. I learned this by experimentation, so there is probably a better and more explicit explanation out there. But with my newbie knowledge, I am going to explain the difference of these two based on what I learned. On a side note, I have not looked up any information pertaining to this topic. This is solely based on what I found out through my trial and error. &lt;/p&gt;




&lt;p&gt;As I was working on a project I ran into a certain snag. Although I ran into a couple of snags along the way, the most significant one for me was the one concerning &lt;code&gt;currentTarget&lt;/code&gt;. Clicking one of the buttons activated two click event functions. One for the button itself, the other for the whole object that the button was a part of. I couldn’t figure out what was the problem at first, but then I realized I had used &lt;code&gt;currentTarget&lt;/code&gt; instead of &lt;code&gt;target&lt;/code&gt; to identify the event target for the click events. Overall its not much of an issue, but since I had two click events that were stacked and part of the same element, it became a problem.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;currentTarget&lt;/code&gt; was not something I had used previously. I used it because it seamed to simplified identifying the whole object that was being clicked on, rather that trying to find the right &lt;code&gt;parentNode&lt;/code&gt;. &lt;code&gt;currentTarget&lt;/code&gt; runs more off of the element that the event listener is placed on, whereas &lt;code&gt;target&lt;/code&gt; is the element on the DOM that is directly being clicked on. Essentially, &lt;code&gt;target&lt;/code&gt; identifies the specific element or tag being clicked on, and &lt;code&gt;currentTarget&lt;/code&gt; identifies the general item being clicked on.&lt;/p&gt;




&lt;p&gt;Since I had &lt;code&gt;div&lt;/code&gt; tags upon &lt;code&gt;div&lt;/code&gt; tags in each card or object, I decided to try using &lt;code&gt;currentTarget&lt;/code&gt; instead. I wanted the click function to work on the whole card, rather than its individual contents or having to stack several &lt;code&gt;parentNode&lt;/code&gt;s. It all worked smoothly until I complicated matters with adding the button inside the card with its own event listener. The button tag as well as its event listener were both inside of the card itself, so the event listener on the whole card would run both, if the button inside was clicked. Moving the button’s event listener outside of the card might have fixed it, but I decided for a more fool-proof method. I decided to add an if statement on my function that would run only if the target of the click was the card, or had the class of “card” to be more specific. I had the if statement use &lt;code&gt;target&lt;/code&gt;, but still used &lt;code&gt;currentTarget&lt;/code&gt; on the function being called inside. This made the event handler still function the same way as before the addition of the button, but clarified the target of the click.&lt;/p&gt;

&lt;p&gt;I ended up adapting this clarification statement to all of my event handlers for this project, to ensure the function I wanted to happen would &lt;em&gt;only&lt;/em&gt; work on the corelating targets. I had a class of "checkbox" or my button, and a class of "card" on the whole card itself. I used the &lt;code&gt;contains&lt;/code&gt; within the if statement, for the clarification of the click target. The event handler for the card click turned out to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// checks if click target is card not checkbox&lt;/span&gt;
    &lt;span class="nx"&gt;getDetail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>functional</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Studio Ghibli Watch List</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Thu, 30 Dec 2021 22:54:22 +0000</pubDate>
      <link>https://dev.to/mailauki/studio-ghibli-watch-list-449p</link>
      <guid>https://dev.to/mailauki/studio-ghibli-watch-list-449p</guid>
      <description>&lt;h3&gt;
  
  
  What can it do?
&lt;/h3&gt;

&lt;p&gt;I made a web application using the Studio Ghibli API. It is a culmination of everything I have learned up to this point in time. I made it with the intended purpose of a watch list, so that the user could mark the Studio Ghibli films that they have watched. The list of films are on the left side, and a more detailed view of a single film on the right. The user can click on a film from the list on the left and have it show on the right with more details, as well as highlight the film on the list that was clicked with a selected view. Both the list and the detailed view have checkbox buttons that correlate to the watched value, so if the user clicks the button the watched value of that specific film with change, from unwatched to watched or vise versa. This action is synced to the film itself, so it doesn't matter if the click has been made on the list or the detail, it will be the same. There is also a filter above the list where the user can filter the list view by whether the film has been marked as watched, as well as which ones were not marked as watched. There are also filters for each of the directors, and for all of the films with no filter active. On a side note, these filters do not stack. The currently active filter will show inside of the filter bar, so the user can always see and know which filter is in use. &lt;/p&gt;




&lt;h3&gt;
  
  
  How does it do this?
&lt;/h3&gt;

&lt;p&gt;Almost all of the functionality of this web application lies in the JavaScript, the rest is CSS. The parts from the CSS that I like best are the button hovering that inverts the button color and changes the cursor, and the combination of the media queries and displays to have the contents adjust to the screen size. &lt;/p&gt;

&lt;p&gt;The initial functionality of this web application are in the fetch requests to the API, which I placed inside of there own functions and called another function with the fetched data to append that data to the DOM. I have two of these fetch requests one for the list and one using an id for the detail, both with they're respective rendering functions. The fetch request functions and rendering functions work in tandem to have the information show on the DOM. I have an extra function which utilizes a while loop to remove the detail's information from the DOM to make room for new information, for when a different film is selected and adds that new information. It acts as a reset for the detailed view. &lt;/p&gt;




&lt;p&gt;I have another fetch request within both of the rendering functions, which is to the JSON file. It checks the value of watched from the stored data, and changes the checkbox accordingly. This way the checkbox appears either checked or unchecked based on the stored data upon the initial appending to the DOM. The only other fetch request is another to the JSON file, which this request is in a function that is called when a click event is triggered. It changes the watched value and updates it on the stored data of the JSON file. The click event triggered is a little complicated. The event listener is on the checkbox button and calls the function dubbed &lt;code&gt;handleCheck&lt;/code&gt;. The first thing that this function does is it identifies the checkbox buttons of the list on the left and the detail on the right. Since there are multiple checkboxes on the list, it turns them into an iterable array. Then if the &lt;code&gt;currentTarget&lt;/code&gt; of the click event is the checkbox button or contains the class of "checkbox" it will call the function with the fetch request to update the JSON file. It then iterates through the array of checkboxes from the list and if the id of the checkboxes match then it change the CSS to make the button appear checked or unchecked. Each of the checkboxes have the id of the film from the API attached as the id, and iterating through the array checks the ids that are already on the DOM so the CSS can change what is already appended to the DOM. The rest of the &lt;code&gt;handleCheck&lt;/code&gt; function checks if the id of the list's checkbox matches the detail's checkbox, and syncs the change in CSS if they do. I also ended up adding the "contains class" if statement to all of my event handlers to clarify the intended target of the click event, so that the functionality would only be applied where its intended in a more fool-proof way. All of this turned out to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;detailCheck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#detail-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cardChecks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#cards-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cardChecksArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;cardChecks&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;detailCheckedBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;detailCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// checks if click target is checkbox&lt;/span&gt;
    &lt;span class="nx"&gt;updateWatched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cardChecksArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cardCheck&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;cardCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// matches click target and list to check of correct checkbox&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checked&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cardCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;detailCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// syncs check of card and detail&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checked&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;cardCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;detailCheckedBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;cardCheck&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
            &lt;span class="nx"&gt;detailCheckedBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Just like the &lt;code&gt;handleCheck&lt;/code&gt; function the &lt;code&gt;handleFilter&lt;/code&gt; function is also a little bit complicated because quite a few things go on inside. Although instead of nested if statements like the &lt;code&gt;handleCheck&lt;/code&gt; function, the &lt;code&gt;handleFilter&lt;/code&gt; function has five &lt;code&gt;else if&lt;/code&gt;s, three of which have a nested if statement. Each of the &lt;code&gt;else if&lt;/code&gt;s act as separate functionality based on what is the desired filter. &lt;/p&gt;

&lt;p&gt;The first thing this function does is make an array of from the list just like in the &lt;code&gt;handleCheck&lt;/code&gt; function. Then it acquires the id of the click target to make sure it is the filter being clicked on, and if it is it displays the dropdown menu. Then on further clicks the function checks the inner text of the clicked target and displays or hides the content based on that text. Which it also identifies the content to display or hide by iterating through all of the cards on the DOM. It also displays the targeted filter within the filter bar, so than what is currently being filtered is visible. All this is excluding “Director” since it simply a label and not a button, and has no functionality other than hovering over in order to display the dropdown menu. All of the functionality within &lt;code&gt;handleFilter&lt;/code&gt; are click events to show and hide items.&lt;/p&gt;

&lt;p&gt;I had initially wanted to use &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;option&lt;/code&gt; tags for the filter, but since I wanted a nested dropdown of directors I could not get the result I wanted. I then switched it to be a &lt;code&gt;ul&lt;/code&gt;, where I could not only have the functionality I wanted but also more easily customize its appearance. Since the functionality lies in the JavaScript, regardless of what tags are used the functionality remains the same, only the application of it an its appearance differ. &lt;/p&gt;




&lt;p&gt;The only other click event for this web application is the one on the list of films itself, which displays the same film in the more detailed view on the right side. Outside of this function, which is only called upon a click event, is another function that runs to match the detail and card, and makes the card appear selected if they are the same. This function is called inside the rendering detail function to more easily acquire the information from the detail as well as reacquiring it once the detail is refreshed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Improvements...
&lt;/h3&gt;

&lt;p&gt;There are a few things I think could be improved upon, but cannot with my current knowledge and abilities. The first being that the selected appearance of the list's film doesn't always show upon the initial load-up, but it works fine with the click event. The other things I disliked where that I had fetch requests inside the rendering functions, rather than in their own separate functions, but I couldn't get it to work the way I wanted otherwise. And for some reason my query selectors wouldn't work in the global scope. I also wish that I could improve its load speed and efficiency, but I currently don't know how to do that while keeping the same functionality. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>css</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>About Me</title>
      <dc:creator>Julie Evans</dc:creator>
      <pubDate>Sun, 24 Oct 2021 16:06:09 +0000</pubDate>
      <link>https://dev.to/mailauki/about-me-3bj9</link>
      <guid>https://dev.to/mailauki/about-me-3bj9</guid>
      <description>&lt;h4&gt;
  
  
  Hello, my name is &lt;strong&gt;Julie&lt;/strong&gt;.
&lt;/h4&gt;

&lt;p&gt;I want to start by introducing myself and why I started my journey into the tech world. To start off with, I am a nerd, like most in this industry. My whole family are nerds, so I come by it honestly, although my family has many different types of nerds and I would be the first to get into programming. I'm from Texas, and my motto is "Go big, or go home." My motto may be a little bit of an ultimatum, but it's what propels me to continue moving forward and succeed. I have another saying that I also use, but not as much, which is "It doesn't hurt to try." I get motivation here as well, because it can be daunting when stepping into uncharted territory, but what's important is trying first?&lt;/p&gt;

&lt;p&gt;I began learning code when I was in high school. I took a class called "Web Design" where I learned the basics of HTML and CSS. I enjoyed that class so much. I was always one or more steps ahead of the pace the class was set at, and I had many pet-projects on the side where I played around with the things I learned. I seemed to be the most enthusiastic one out of my class, to the point where I was the &lt;em&gt;teacher's pet&lt;/em&gt;. I felt a little alone despite being in a class of 30. The rest of the class seemed to treat the assignments begrudgingly, while I was a glutton who wanted to learn as much as possible. At the time there wasn't a class after which to continue my education in coding, so I put it aside and moved on.&lt;/p&gt;

&lt;p&gt;After which, I graduated High School and went on to College. I ended up focusing on learning Linguistics, Anthropology, and Japanese. I had enjoyed all of the classes and topics I learned about in College, but I had completely forgotten about coding and how much I had enjoyed learning it. It wasn't until after I had graduated and was trying to find my calling, with little success, that it came like an epiphany. A spark of a moment that came out of nowhere, I remembered about coding and my love for it. I felt a little disappointed that I had forgotten so completely about something I enjoyed so much. I also felt excited because my gut was telling me that this might be &lt;em&gt;it&lt;/em&gt;, the thing I had been searching for all these years, what I wanted to invest myself in and pursue as my career.&lt;/p&gt;

&lt;p&gt;Now that I have graduated from College and working towards making my career, I thought that now was the opportune moment to try to get back into coding and to go into programming. It felt like fate, and I went with my gut decision to go for it. I haven't had a single important life decision where I went with my gut that I have regretted. If anything, my deep love of Linguistics and anything Language, which I explored in College, can propel me forward and be applied to tech as well. Because what is a programming language but just another language. &lt;/p&gt;

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