<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dorthy Thielsen</title>
    <description>The latest articles on Forem by Dorthy Thielsen (@dotnotation).</description>
    <link>https://forem.com/dotnotation</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%2F631285%2F162350d6-9479-4a95-8239-910976278037.jpg</url>
      <title>Forem: Dorthy Thielsen</title>
      <link>https://forem.com/dotnotation</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dotnotation"/>
    <language>en</language>
    <item>
      <title>Post Bootcamp Graduation Advice</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Tue, 03 Jan 2023 18:46:27 +0000</pubDate>
      <link>https://forem.com/dotnotation/post-bootcamp-graduation-advice-3mnl</link>
      <guid>https://forem.com/dotnotation/post-bootcamp-graduation-advice-3mnl</guid>
      <description>&lt;p&gt;A new year and the job search continues. Hopefully the new year will bring me into my new career. &lt;/p&gt;

&lt;p&gt;With that said, I have some exciting news. I just started a volunteer web developer position and my first stand up is tomorrow. I am really excited for this opportunity and excited to work on a professional team of other developers. &lt;/p&gt;

&lt;p&gt;Last year was hard on the tech industry and well, everyone. To any fellow graduates from last year, keep your head up and go easy on yourself. It has been hard for everyone to find a job, especially junior developers. I have definitely spiraled a lot this year with thinking I am not good enough, but forgetting that it was just a bad year to be switching into the field. If you also did the Flatiron Bootcamp, I highly suggest taking a supplementary algorithm and data structure class and doing lots of leetcode. I am currently taking Colt Steele's JavaScript Algorithm and Data Structures masterclass through Udemy and it has helped me so much. I do great in my interviews, but then the technical interview shows up and often I have been given a data structure I haven't used before. I was practicing for an interview for a company and saw a lot of the practice questions dealt with stacks and binary search trees, which I knew nothing about. I studied the masterclass as much as I could before the interview and felt more prepared than I ever had before. It was nice that this interview also had a real person that I could talk to and bounce ideas off of. It is great to talk things out with someone else so you don't get stuck and panic which is what tends to happen when I have been doing the unpaired interviews. Just remember to breathe and do the best you can. Always write out pseudocode first. Think about what are your inputs and outputs. What are your edge cases? Can you get around sorting and nested loops to save on your time and space complexity? If you are stuck on some aspect, code a simpler solution that maybe doesn't meet all parameters but at least gets you going in the right direction. &lt;/p&gt;

&lt;p&gt;I also wanted to provide some information on the different data structures I have learned about so far. I hope this little cheat sheet will help you in your engineering/developer journey. Wishing everyone a better year!&lt;/p&gt;

&lt;p&gt;Stacks: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data collections&lt;/li&gt;
&lt;li&gt;abstract data structure

&lt;ul&gt;
&lt;li&gt;basically a set of rules for storing data in a certain way&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;needs a last in first out (LIFO) data structure 

&lt;ul&gt;
&lt;li&gt;the last element added to the stack will be the first element removed from the stack&lt;/li&gt;
&lt;li&gt;similar to the call stack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Where are stacks used?

&lt;ul&gt;
&lt;li&gt;managing function invocations&lt;/li&gt;
&lt;li&gt;undo/redo functionality 

&lt;ul&gt;
&lt;li&gt;think of how photoshop undos the last action &lt;/li&gt;
&lt;li&gt;routing (the history object) is treated like a stack&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;array implementation

&lt;ul&gt;
&lt;li&gt;JS does not have a built in method for stacks &lt;/li&gt;
&lt;li&gt;use .push()  and .pop()  on an array makes a stack&lt;/li&gt;
&lt;li&gt;can use .unshift()  and shift()

&lt;ul&gt;
&lt;li&gt;however this is more cost heavy because everything has to be re-indexed everytime &lt;/li&gt;
&lt;li&gt;also note that you can either use push and pop OR unshift and shift
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;linked list implementation&lt;/li&gt;
&lt;li&gt;Big O

&lt;ul&gt;
&lt;li&gt;insertion O(1)&lt;/li&gt;
&lt;li&gt;deletion O(1)&lt;/li&gt;
&lt;li&gt;access O(n)&lt;/li&gt;
&lt;li&gt;searching O(n)
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Queues: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First in first out (FIFO) data structure&lt;/li&gt;
&lt;li&gt;adding and removing &lt;/li&gt;
&lt;li&gt;array implementation 

&lt;ul&gt;
&lt;li&gt;var queue = []&lt;/li&gt;
&lt;li&gt;can use push and  shift

&lt;ul&gt;
&lt;li&gt;heavy to use because of having to reindex&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;can use unshift and pop

&lt;ul&gt;
&lt;li&gt;also heavy with the reindex &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;linked list implementation

&lt;ul&gt;
&lt;li&gt;lighter weight&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Big O

&lt;ul&gt;
&lt;li&gt;insertion O(1)&lt;/li&gt;
&lt;li&gt;deletion O(1)&lt;/li&gt;
&lt;li&gt;access O(n)&lt;/li&gt;
&lt;li&gt;searching O(n)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Types&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there are so many types however we focus on the following&lt;/li&gt;
&lt;li&gt;tree&lt;/li&gt;
&lt;li&gt;binary tree

&lt;ul&gt;
&lt;li&gt;each node can have at most two children &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;binary search tree

&lt;ul&gt;
&lt;li&gt;special case of a binary tree&lt;/li&gt;
&lt;li&gt;each node can have at most two children &lt;/li&gt;
&lt;li&gt;sorted in a particular way &lt;/li&gt;
&lt;li&gt;used to store data that is comparable/ sortable &lt;/li&gt;
&lt;li&gt;if you take any node on the tree,  every item that is less than that node is located to the left, and every item that is greater than is to the right &lt;/li&gt;
&lt;li&gt;great insertion and searching as it is sorted&lt;/li&gt;
&lt;li&gt;the root is going to be a half way point so it makes it easier to compare and traverse &lt;/li&gt;
&lt;li&gt;compare and go to the left or the right, each time, you are cutting your options in half &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great for web scraping nested HTML&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a step up from linked lists&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;a data structure that consists of nodes in a parent/child relationship or a hierarchical structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;type of a graph&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;think of a branching tree but upside down&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;root - the top node from which everything branches from&lt;/li&gt;
&lt;li&gt;child - a node directly connected to another node when moving away from the root&lt;/li&gt;
&lt;li&gt;parent - the converse notion of a child&lt;/li&gt;
&lt;li&gt;sibling - a group of nodes with the same parent&lt;/li&gt;
&lt;li&gt;leaf - a node with no children/ the end of the line &lt;/li&gt;
&lt;li&gt;edge - the connection between one node and another&lt;/li&gt;
&lt;li&gt;basically root connects to a parent which connects to a child, think of how state works in React&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;nonlinear &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there can be many ways to reach a branching path &lt;/li&gt;
&lt;li&gt;a linked list is linear as there is only one direction you can go &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;not a tree&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if there are nodes that reference each other on the same level  (sibling) aka they reference nodes that are not below them (children)

&lt;ul&gt;
&lt;li&gt;a node on a tree can only reference their children &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;there can only be one root/ entry point&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;USES&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML DOM

&lt;ul&gt;
&lt;li&gt;the connection between each element &lt;/li&gt;
&lt;li&gt;think of how the body contains different div which have divs inside that, etc. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;network routing&lt;/li&gt;
&lt;li&gt;abstract syntax trees&lt;/li&gt;
&lt;li&gt;artificial intelligence &lt;/li&gt;
&lt;li&gt;folders in operating system&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Heaps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great for schedule/ priority task list&lt;/li&gt;
&lt;li&gt;a type of tree&lt;/li&gt;
&lt;li&gt;types: binary, fibonacci, pairing, leftist, etc. &lt;/li&gt;
&lt;li&gt;Binary Heaps

&lt;ul&gt;
&lt;li&gt;two types: min and max heaps

&lt;ul&gt;
&lt;li&gt;MaxBinaryHeap

&lt;ul&gt;
&lt;li&gt;parent nodes are always larger than child nodes&lt;/li&gt;
&lt;li&gt;what makes it different from a Binary Search Tree is that the children are smaller and the order of the children doesn't matter&lt;/li&gt;
&lt;li&gt;root is always the largest&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;MinBinaryHeap

&lt;ul&gt;
&lt;li&gt;parent nodes are always smaller than child nodes&lt;/li&gt;
&lt;li&gt;root is always the smallest&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;similar to a binary search tree, but with different rules&lt;/li&gt;
&lt;li&gt;at most each parent can have two children &lt;/li&gt;
&lt;li&gt;compact as possible 

&lt;ul&gt;
&lt;li&gt;every left and right are filled out before moving up&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;used to implement priority queues and with graph traversal algorithms&lt;/li&gt;
&lt;li&gt;can use an array to store a binary heap&lt;/li&gt;
&lt;li&gt;for any index of an array (n) the left child is stored at 2n + 1 and the right child is at 2n + 2&lt;/li&gt;
&lt;li&gt;for any child node at index n, its parent is at index Math.Floor((n -1) / 2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hash Tables: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aka hash map aka object (but with restrictions as objects typically deal with strings)&lt;/li&gt;
&lt;li&gt;built in to almost every programming language as a default type 

&lt;ul&gt;
&lt;li&gt;Python = dictionaries&lt;/li&gt;
&lt;li&gt;JS = objects and maps&lt;/li&gt;
&lt;li&gt;Java, Scala, and Go  = maps&lt;/li&gt;
&lt;li&gt;Ruby = hashes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;used to store key-value pairs&lt;/li&gt;
&lt;li&gt;not ordered&lt;/li&gt;
&lt;li&gt;fast for all operations &lt;/li&gt;
&lt;li&gt;hash function

&lt;ul&gt;
&lt;li&gt;implementing a hash table by using an array which you convert keys into valid array indices &lt;/li&gt;
&lt;li&gt;any function that can be used to map data of arbitrary size to data of a fixed size

&lt;ul&gt;
&lt;li&gt;so basically no matter what size the input is, it could be one or million characters, the output will always be the same size&lt;/li&gt;
&lt;li&gt;however the output isn't something you can work backwards from, it is encrypted &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;the values returned are called hash values, hash  codes, digests, or simply hashes&lt;/li&gt;
&lt;li&gt;used in caches, crypto, authentication &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;What makes a good hash

&lt;ul&gt;
&lt;li&gt;O(1)&lt;/li&gt;
&lt;li&gt;doesn't cluster outputs at specific indices, but distributes uniformly &lt;/li&gt;
&lt;li&gt;deterministic, every time you put in the same input you get the same output&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;handle collision

&lt;ul&gt;
&lt;li&gt;when you have a hash function it is inevitable that you will have data that will be assigned the same index especially with small arrays like in the example&lt;/li&gt;
&lt;li&gt;separate chaining 

&lt;ul&gt;
&lt;li&gt;you store pieces of data at the same spot/index in a more sophisticated data structure like a linked list or nested array

&lt;ul&gt;
&lt;li&gt;this allows you to store multiple key-value pairs at the same index&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;linear probing

&lt;ul&gt;
&lt;li&gt;you only store one piece of information at each index, if you have a collision/duplicate, then you search through the array and find the next empty spot&lt;/li&gt;
&lt;li&gt;allows you to avoid nested data structures &lt;/li&gt;
&lt;li&gt;however you have to decide what you are going to do when you run out of room in your array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Big O

&lt;ul&gt;
&lt;li&gt;insertion O(1)&lt;/li&gt;
&lt;li&gt;deletion O(1)&lt;/li&gt;
&lt;li&gt;access O(1)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Graphs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a data structure that consists of a finite (and possibly mutable) set of vertices or nodes or points, together with a set of unordered pairs of these vertices for an undirected graph or a set of ordered pairs for a directed graph &lt;/li&gt;
&lt;li&gt;a collection of nodes and connections between those nodes &lt;/li&gt;
&lt;li&gt;a tree is a type of graph&lt;/li&gt;
&lt;li&gt;no starting point or parent node&lt;/li&gt;
&lt;li&gt;models relationships&lt;/li&gt;
&lt;li&gt;uses

&lt;ul&gt;
&lt;li&gt;great for map/location data&lt;/li&gt;
&lt;li&gt;user data&lt;/li&gt;
&lt;li&gt;recommendation on social media&lt;/li&gt;
&lt;li&gt;routing &lt;/li&gt;
&lt;li&gt;visual hierarchy&lt;/li&gt;
&lt;li&gt;file system optimizations &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Parts

&lt;ul&gt;
&lt;li&gt;vertex - a node&lt;/li&gt;
&lt;li&gt;edge - connection between nodes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;types

&lt;ul&gt;
&lt;li&gt;directed graph

&lt;ul&gt;
&lt;li&gt;the edge has polarity or direction&lt;/li&gt;
&lt;li&gt;directions assigned to distance between vertices&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;undirected graph

&lt;ul&gt;
&lt;li&gt;no direction between the edges&lt;/li&gt;
&lt;li&gt;can traverse in any direction&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;weighted graph

&lt;ul&gt;
&lt;li&gt;values assigned to distances between vertices&lt;/li&gt;
&lt;li&gt;the edge has a value&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;unweighted graph

&lt;ul&gt;
&lt;li&gt;no value to each edge&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;can be any combination of these&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implementations

&lt;ul&gt;
&lt;li&gt;adjacency matrix

&lt;ul&gt;
&lt;li&gt;has vertices and edges &lt;/li&gt;
&lt;li&gt;2D structure usually implemented with nested arrays with rows and columns &lt;/li&gt;
&lt;li&gt;takes up more space&lt;/li&gt;
&lt;li&gt;slower to iterate over all edges&lt;/li&gt;
&lt;li&gt;faster to lookup specific edge&lt;/li&gt;
&lt;li&gt;for lots of data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;adjacency list

&lt;ul&gt;
&lt;li&gt;use an array or list to store the edges &lt;/li&gt;
&lt;li&gt;or can store as hash table/object&lt;/li&gt;
&lt;li&gt;can take up less space&lt;/li&gt;
&lt;li&gt;faster to iterate over all edges&lt;/li&gt;
&lt;li&gt;can be slower to lookup specific edge&lt;/li&gt;
&lt;li&gt;most real world data tends to lend itself to adjacency lists as the data is sparse&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Singly Linked Lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an ordered list with fast inserts/removals at the beginning and end

&lt;ul&gt;
&lt;li&gt;as compared to arrays where shift and unshift are costly&lt;/li&gt;
&lt;li&gt;although random access is not allowed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;a data structure that contains a head, tail, and length property

&lt;ul&gt;
&lt;li&gt;from the head you can figure out the next element &lt;/li&gt;
&lt;li&gt;think of it as a skyscraper without an elevator, you have to take the stairs and access each floor individually from the beginning&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;consist of nodes

&lt;ul&gt;
&lt;li&gt;node is a piece of data or element&lt;/li&gt;
&lt;li&gt;refers the next node&lt;/li&gt;
&lt;li&gt;each node has a value and a pointer to another node || null&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;a bunch of elements with no index pointing to the next element&lt;/li&gt;
&lt;li&gt;you have to start at the beginning to access elements&lt;/li&gt;
&lt;li&gt;excel at insertion and deletion and you don't need to access a random element &lt;/li&gt;
&lt;li&gt;foundation to stacks and queues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doubly Linked Lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is a singly linked list but adding a pointer to prev node and next node&lt;/li&gt;
&lt;li&gt;it is more flexible than a singly linked list, but it costs more memory&lt;/li&gt;
&lt;li&gt;no index, just pointers to the previous and next element&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>First Hackathon</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Wed, 21 Sep 2022 19:23:01 +0000</pubDate>
      <link>https://forem.com/dotnotation/first-hackathon-l82</link>
      <guid>https://forem.com/dotnotation/first-hackathon-l82</guid>
      <description>&lt;p&gt;Last month I participated in my first hackathon! This was the third part of my interview for JP Morgan Chase Emerging Talent Software Engineer. While I didn't end up getting a position from this, I learned a lot along the way.&lt;/p&gt;

&lt;p&gt;Let's start at the beginning of the interview. The first step of the interview was recorded video responses, which was so bizarre to me. The entire way through this interview, I didn't get to talk to a human one on one. I am so used to speaking to someone else that it was hard for me to really bring my full personality to the recorded interview responses. &lt;/p&gt;

&lt;p&gt;Second was the technical interview. I am still learning more about data structures and algorithms so I struggled a bit with this section and psyched myself out during it. I am currently working on Colt Steele's Udemy JS algorithms and data structures masterclass so I will be more prepared in the future. &lt;/p&gt;

&lt;p&gt;The final piece was the hackathon. It was a 12 hour block with about 2 hours of introductions, and presenting. I had no idea that you would be able to meet with your time the night before and wish I would have known so I could have taken the time off so I could have been more present during the meeting. Since I was working, I was only able to listen into the meeting but really couldn't add much to the discussion. We decided to do Python for the backend and React for the frontend. We divided our team in half and I was part of the React frontend team. Before we started coding, we discussed the given problem, our goals, and our data types. Our first mentor really just left us alone and seemed really busy so we thought we were on the right track. I was in charge of taking notes, assigning tasks, and keeping track of progress. After everything was discussed, we broke off into frontend and backend and started coding. I was in charge of create account and logging in. I was feeling good but we were already 4 hours into our time and our second mentor came in. I really appreciate our second mentor but he definitely changed everything. I wish he would have been there at the beginning to start us done the right path. He said our scope was too big, and it was. We were trying to do too many things at once and there was no way we were going to get done. He said that the first thing to scrap was the log in and create account because every project has that and it isn't unique or innovative. With this, all my code was tossed out. I then decided to help the other two people in the frontend team with their pages instead. Time flew by after this. We kept checking in with the backend and they were struggling getting the database in place. With only an hour left in our coding time, the database was finally ready to call however none of us on the frontend were used to calling a database in Python and realized we didn't have enough time to figure it out. We decided to hard code in our data so we had something to show during our presentation. We quickly figured out our presentation and were the first to present. I am pleased with what we accomplished and definitely learned a lot during the hackathon.&lt;/p&gt;

&lt;p&gt;My advice for anyone doing a hackathon is to focus on one feature at a time. Start with the simplest data and the most unique feature and work off of that. Set aside time the night before to talk to your team. Make sure to keep notes and keep organized. They are definitely looking for people who aren't afraid to talk up and take control of a situation. Two people got job offers from my group and it was pretty clear why they got those offers. They did the most coding and they were not afraid to speak up. Another thing I wish I would have known was how many people would be participating in the hackathon. In my group it was 400 people! I wasn't expecting that many people to make it to that point. I am not sure if people get eliminated along the way or if everyone gets to participate in the hackathon. Also make sure you prepare food and have water close by. You are going to need the energy. I will definitely be reapplying and doing more hackathons in the future. If you are reading this and about to go into a hackathon, I am wishing you the best of luck!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
      <category>python</category>
    </item>
    <item>
      <title>Post Graduation and Mock Technical Interview</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Fri, 20 May 2022 19:46:30 +0000</pubDate>
      <link>https://forem.com/dotnotation/post-graduation-and-mock-technical-interview-46j9</link>
      <guid>https://forem.com/dotnotation/post-graduation-and-mock-technical-interview-46j9</guid>
      <description>&lt;p&gt;On March 24th I graduated the Flatiron Full Stack Dev bootcamp. It was a wild ride being the bootcamp and I am so excited to be done and starting my new career. I wanted to give my thoughts on the Flatiron bootcamp, and the Skilled mock technical interview.&lt;/p&gt;

&lt;p&gt;What probably most people are wondering is was the bootcamp worth it? In short, I would say yes. I had no coding knowledge or experience going in so I would have had no idea where to start teaching myself. I liked how the lessons built on each other and how you could see how the information could be used in different languages other than the ones they teach. In retrospect, I wish I would have done the in person or more structured bootcamp. I wasn't able to due to my schedule at the time, but having watched the lectures from previous cohorts, the information was presented in a more digestible  way. If you do the self-paced course like I did, pick a previous cohort and watch all the videos as you go. I really liked Laura's and Eri's cohort the best. I watched a lot of self-paced students really struggle through and if it wasn't for my determination, I don't know how I would have every completed the course. It is tough to stay motivated when you feel like you are all by yourself. The study groups are also really helpful. Most of the time it is just people asking about questions on their final project, but I learned a lot from that even when I wasn't familiar with the concept. I would record the study group and when I came across the topics in the course, I would go back and watch that section of the study group again. Dustin, who is the self-paced cohort lead, was so helpful and would often live code and talk about a particular subject and it was so great to watch. I was always so nervous for the final assessments for each section, but I always passed on my first go. I feel really great about that accomplishment. &lt;/p&gt;

&lt;p&gt;Here is my constructive criticism on the bootcamp. Some of the lessons are really hard to understand. Some of the labs have absolutely no instructions and have really weird tests with no good feedback. For example, a few times because I named a class something different, my tests wouldn't pass but it wouldn't say that it couldn’t find the class but would give a different weird error. The React section, which was my favorite, is very outdated. The recently started adding additional content on hooks, but unless you know to seek it out, you will be going into technical interviews with very outdated information. Luckily I was watching Laura's cohort videos and she teaches hooks. She also gave a lot of good resources for me to use to also teach myself about them. I used hooks in my final project and am obsessed with hooks now. &lt;/p&gt;

&lt;p&gt;Speaking of hooks and React, after graduation you get a token to have a mock technical interview through Skilled. I decided to take the React assessment. I passed with flying colors and it was a great interview. Hyung Kim was my assessor and was so nice and put me at ease immediately. The question section asked mostly about broad topics about React. Questions like: What is JSX? What are hooks and how do you use them? How do you store state? Explain class versus functional components. Is there a better way to store state and what library would you recommend using? What is &lt;code&gt;useEffect&lt;/code&gt; and what is the dependency array it takes in? What if you leave that array empty?&lt;/p&gt;

&lt;p&gt;For the live coding I had to make a counter button that increased and decreased. I then had to put a limit on it so it couldn't go below 0 or passed ten. For the next section, I had to call an API and display information from the API. The only hooks I used for both of these were &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt;. I of course made a few tiny mistakes but was able to quickly fix them without a lot of hints. Overall I am really proud of myself for being able to live code in front of other people and be able to answer all of their questions. &lt;/p&gt;

&lt;p&gt;Here is the feedback I got about my technical interview: "Dorthy was a great candidate to talk too! She was very professional and nice during the entire interview process. We started the interview with brief introductions of each other where we discussed experience and future endeavors. We first started the interview process by discussing high level conceptual questions in which she did a great job answering on! She was able to answer each and everyone of those questions clearly. Next, we moved onto a code challenge in which involved multiple rounds of questions. She did a very good job of walking me through the challenge question as well. Well on her way to be a successful engineer!"&lt;/p&gt;

&lt;p&gt;With all of this said, I am really happy I took this leap of faith into a new career. It has been a humbling and rewarding process. It wasn't an easy journey by any means but I worked really hard. The thing that has also been so great is how supportive other engineers have been. Every single person I have interacted with has been so helpful and kind. There are no secrets, everyone wants to help each other and that is so refreshing. That was something I never really liked about puppet fabrication were all the trade secrets that people didn't want to tell you. I always shared any information I knew with other people. Even places I worked at for years wouldn't tell me some of the materials and techniques. Even one boss would take the labels off of some of the materials and would do work after hours to keep his trade secrets to himself. I think that is part of the reason the industry is suffering so much. It is such a breath of fresh air to be in a new environment that is so nurturing. I am now looking for jobs and hoping to land something soon. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>React/Redux Final Project</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Sun, 13 Mar 2022 18:16:59 +0000</pubDate>
      <link>https://forem.com/dotnotation/reactredux-final-project-3j4g</link>
      <guid>https://forem.com/dotnotation/reactredux-final-project-3j4g</guid>
      <description>&lt;p&gt;Today I am going to turn in my final, final project for the Flatiron Bootcamp. It is a really weird feeling. Part of me thinks I can’t possibly be done. Although I still have to do my final assessment plus all the post bootcamp work. Part of me also feels like I still have so much to learn, how could I be done. I think that feeling will always be there a bit. There is still so much to learn, but I have exhausted the bootcamp and will need to turn to other outlets for my continuing education.&lt;/p&gt;

&lt;p&gt;For this project, I decided to redo my vanilla JS project. This was intentional as I wasn’t really happy with my JS project and really wanted a chance to do it better. I also wanted to use hooks and React Router 6 for my project, which the curriculum doesn’t really go over all too well. I wanted to challenge myself to use these things that were a bit out of scope for the course. The format of React is so different from JS and also dealing with state and Redux that I wanted to concentrate on that instead of worrying about the data I was displaying. I also wanted to focus on doing full CRUD, and there wasn’t anything on editing data in the labs so I knew that would be a challenge to figure out. It was also a big shift from using class and presentational components and switching to all functional components. Do I love my solution for editing details? No. Do I want to change this at some point? Yes. However I came to a point where I felt that the project was good enough to turn in. I will never be 100% happy with every aspect of my code. There is always room for improvement. With things changing so much in my personal life right now, I just needed to call this good enough for now and proceed to graduate. Graduating is terrifying. I know that if I don’t take this chance, I will just keep putting off this last step. &lt;/p&gt;

&lt;p&gt;Let’s go over the hooks I used in my project. First, &lt;code&gt;useSelector()&lt;/code&gt; which maps state to props and replaces you having to use &lt;code&gt;connect()&lt;/code&gt;. &lt;code&gt;useSelector()&lt;/code&gt; takes an argument of a callback function that will take in the state from your store and then return the value that you want to set as a state variable. I did learn that if you are using multiple reducers and are using &lt;code&gt;combineReducers&lt;/code&gt; your callback function needs to dig into the nested reducer information via &lt;code&gt;state =&amp;gt; state.petReducer.pets&lt;/code&gt;. This is just saying in my state, go to the petReducer and from that reducer I want to access the pets’ information. Next hook I used, that is the foil to &lt;code&gt;useSelector()&lt;/code&gt; is &lt;code&gt;useDispatch()&lt;/code&gt;. This hook replaces &lt;code&gt;mapDispatchToProps&lt;/code&gt; in &lt;code&gt;connect()&lt;/code&gt;. Between these two hooks we have no use for &lt;code&gt;connect&lt;/code&gt; in this project anymore.  The next big one was &lt;code&gt;useState()&lt;/code&gt; which lets you set the initial state. You can’t nest this inside of other functions.  It returns an array, the first is the state value and the second is the function to change that value. This hook was so handy in forms. &lt;code&gt;const [name, setName] = useState(‘’)&lt;/code&gt; allows you to set the state of name to an empty string and then you can use this in your form as the value. Then for your &lt;code&gt;onChange&lt;/code&gt; you can use a callback function to &lt;code&gt;setName&lt;/code&gt; to the &lt;code&gt;e.target.value&lt;/code&gt; via &lt;code&gt;onChange={e =&amp;gt; setName(e.target.value)}&lt;/code&gt;. Now the state of &lt;code&gt;name&lt;/code&gt; will be whatever is input in the form. You can also set the initial state to a previous value. I used this in my edit forms to have the input be auto populated with information from the entry that is being edited. This is where &lt;code&gt;useNavigate()&lt;/code&gt; and &lt;code&gt;useLocation()&lt;/code&gt; came in handy to pass state from one component to another. First, you set &lt;code&gt;useNavigate()&lt;/code&gt; to a constant to use the function as you can’t pass a hook to Redux and it is a rule of hooks. &lt;code&gt;const navigate = useNavigate()&lt;/code&gt;. The simplest way to &lt;code&gt;useNavigate()&lt;/code&gt; is with a back button. All you have to do is &lt;code&gt;onClick={() =&amp;gt; navigate(-1)}&lt;/code&gt; and the user will be taken to the previous page. Pretty cool, right? This hook replaces &lt;code&gt;useHistory()&lt;/code&gt; from React Router 5. Since I am using React Router 6, I had to use &lt;code&gt;useNavigate()&lt;/code&gt; The first time I used this was to pass information from a pet down to it’s toys. So on my event handler for the open toy box button, I used &lt;code&gt;navigate(“/toys”, {state: { pet_id: props.id, name: props.name}})&lt;/code&gt;. The first argument is the location and the second argument is the state you want to pass down. So I want to navigate to /toys and I want the state of that pet’s id and name. To use this information, you need to use the next hook &lt;code&gt;useLocation()&lt;/code&gt;. Again you set a variable to be equal to the function of the hook &lt;code&gt;const location = useLocation()&lt;/code&gt;. Then we can set variable to be equal to the state being passed &lt;code&gt;const petName = location.state.name&lt;/code&gt;. Now I have access to that pet’s name inside of my toy component so I can display their name at the top of their toy list. This also was needed so I had access to the pet’s id. Since toys belong to pet and a pet has many toys, I needed a way to persist the pet’s information to the toy and pass in the correct pet id to the toys. For instance in the toy form, there is a hidden field of the pet’s id so the toy is properly saved with the current pet linked. The last hook is &lt;code&gt;useEffect()&lt;/code&gt; which allows you access to lifecycle methods similar to &lt;code&gt;componentDidMount()&lt;/code&gt;. It is a function that takes in a callback function and an array of dependencies that determines when the callback function is called. If you don’t pass in any dependencies, the function will only run on first render. This is a great place to call anything that needs dispatched, like fetching a list to be rendered, which you only need to happen upon first render. &lt;/p&gt;

&lt;p&gt;I also played with an animation with CSS which was really fun. I tried to get more comfortable with &lt;code&gt;className&lt;/code&gt; inline CSS during this project. In general I tried to really challenge myself with this project and try things that scared me or were too intimidating before. You can check out my &lt;a href="https://github.com/dotnotation/Furmiliar_React_Frontend"&gt;frontend repo&lt;/a&gt; and my &lt;a href="https://github.com/dotnotation/Furmiliar_React_Backend"&gt;backend repo&lt;/a&gt;. I do plan to work more on this project after graduating. Wish me luck on my assessment! See you on the other side.   &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>redux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Quote Maker Lab: Redux/React</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Wed, 23 Feb 2022 21:53:59 +0000</pubDate>
      <link>https://forem.com/dotnotation/quote-maker-lab-reduxreact-ek7</link>
      <guid>https://forem.com/dotnotation/quote-maker-lab-reduxreact-ek7</guid>
      <description>&lt;p&gt;I am getting so close to finishing my bootcamp at Flatiron. I have finished React and am diving into Redux. I will say that when I started learning React, the thought of where to store state was a bit overwhelming. When I started drawing out my node trees, that got a lot easier. Then came in Redux and the idea of the store where all your state is conveniently held. I was actually a little bummed because I really felt like I had a grasp on state in React and now came in this thing to make things easier. Although I will say the text has been a little confusing where it will say to not always use the store, but use the store. Still figuring things out, but that is the whole experience of coding, right? &lt;/p&gt;

&lt;p&gt;I wanted to go over this Redux lab in the bootcamp that seemed overwhelming when I started it. It was the first large lab in the Redux section. It is called the Quote Maker Lab. Basically you have a form where you can submit quotes and the author of those quotes and then you want those quotes to show up on the page with all the information, plus a down vote, up vote, and delete button with all their functionality built in. &lt;/p&gt;

&lt;p&gt;To start chipping away at this lab, I first mounted the main components to my &lt;code&gt;App.js&lt;/code&gt;, those being &lt;code&gt;&amp;lt;QuoteForm /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Quotes /&amp;gt;&lt;/code&gt;. By adding those to the &lt;code&gt;render()&lt;/code&gt; my page was already starting to look better as the there was some code provided in this lab to render a basic form and the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;s. Always remember to import the corresponding files into &lt;code&gt;App.js&lt;/code&gt; via &lt;code&gt;import QuoteForm from "./components/QuoteForm"&lt;/code&gt;. Also quick note: adding &lt;code&gt;.js&lt;/code&gt; to the end of your file name is optional when importing. I personally always leave it off. Then I ran the tests provided to see where to start. The first step the tests wanted me to do was to deal with the action creators, in this case they were &lt;code&gt;addQuote&lt;/code&gt;, &lt;code&gt;removeQuote&lt;/code&gt;, &lt;code&gt;upvoteQuote&lt;/code&gt;, and &lt;code&gt;downvoteQuote&lt;/code&gt;. All action creators are just functions that you are exporting. All of these functions need to return an object with a type and a payload. I wanted to show you that you can write these either multiline or as an arrow function:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;downvoteQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quoteId&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;// should return an object with a type of "DOWNVOTE_QUOTE" and a quoteId&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOWNVOTE_QUOTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;quoteId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;quoteId&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// or as an arrow function:&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;downVote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quoteId&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOWNVOTE_QUOTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quoteId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;quoteId&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically all the actions pretty much looked like this but with a different &lt;code&gt;type&lt;/code&gt;. With all these action creators down it was on to the &lt;code&gt;QuoteCard&lt;/code&gt; Component as that was the next one listed in the test. This component already had some code, but was missing its &lt;code&gt;props&lt;/code&gt; to display the content. This test being next seemed a bit strange especially because we haven't gotten to how props are being passed down. In the &lt;code&gt;README&lt;/code&gt;, the example of the object that is being created only has attributes of id, content, and author, no mention of votes. However I added in &lt;code&gt;props.quote.author&lt;/code&gt;, &lt;code&gt;props.quote.content&lt;/code&gt;, and &lt;code&gt;props.quote.votes&lt;/code&gt; to the card rendering from this component. I will come back to showing the votes later on as currently this code won't work. &lt;/p&gt;

&lt;p&gt;The next test was for the &lt;code&gt;QuoteForm&lt;/code&gt; component which will allows us to start dealing with state and those props previously mentioned. This component had some provided code for the form, but it currently had no functionality. I first wanted to tackle the state with some key/value pairs.&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="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Something I immediately noticed with the form provided was that there was no unique identifier between the input fields, so I added a name to each. This will allow us to handle events easier as you will soon see. Also currently the form doesn't work when you try to type in it, so a &lt;code&gt;onChange&lt;/code&gt; event handler needed to be added to each input. Now the inputs looked like:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
                        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form-control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                        &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleOnChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                      &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next was to tackle the &lt;code&gt;onChange&lt;/code&gt; event handler to handle updating the components state and allow for the input fields to work. By previously adding the name attribute to each input field, I no longer have to write out each key/value pair in this method, but can just call on the event's target's name. A quick note: the reason &lt;code&gt;event.target.name&lt;/code&gt; has to be in brackets is because we are getting the key from an operation and we just want the value from that operation.&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="nx"&gt;handleOnChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;event&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;name&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;event&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;value&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;Now to tackle submitting the form. First I am going to add the &lt;code&gt;onSubmit={this.handleOnSubmit}&lt;/code&gt; to the form so that the event can be handled. As with almost any submit, we want to &lt;code&gt;preventDefault()&lt;/code&gt; so the page doesn't automatically refresh on submit. Then we want to create a quote object from state. In this lab we are using &lt;code&gt;uuid()&lt;/code&gt; to create our unique id's for every instance. Next is to pass the quote object to the action creators that we created earlier in this lab. When we are submitting a form, we want to create an object so the only action creator that makes sense is &lt;code&gt;addQuote&lt;/code&gt;. We need to connect to the store in order to do this via &lt;code&gt;connect()&lt;/code&gt;. The thing we always need to do with actions is to dispatch them via &lt;code&gt;mapDispatchToProps&lt;/code&gt;. This way we are getting access to dispatch so we can dispatch the return value of those actions to the reducer. This way we can call dispatch in our &lt;code&gt;handleOnSubmit&lt;/code&gt; via &lt;code&gt;this.props.dispatchAddQuote(quote)&lt;/code&gt;. Then we want to return state to default so the form clears out.&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="nx"&gt;handleOnSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle Form Submit event default&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// Create quote object from state&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Pass quote object to action creator&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchAddQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Update component state to return to default state&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;dispatchAddQuote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addQuote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quote&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="c1"&gt;//add arguments to connect as needed&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;QuoteForm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to look at our reducers. First is to see how the reducers are being connected to the store in &lt;code&gt;index.js&lt;/code&gt;.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;rootReducer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reducers/index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootReducer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's quickly go back to the &lt;code&gt;QuoteCard&lt;/code&gt; even though it is revisited in the last two tests. This way we can visually see if our reducers are working. We want to render the &lt;code&gt;&amp;lt;QuoteCard /&amp;gt;&lt;/code&gt; in our &lt;code&gt;Quote&lt;/code&gt; container. First we must gain access to our quotes via &lt;code&gt;connect()&lt;/code&gt; and &lt;code&gt;mapStateToProps&lt;/code&gt;. We could just write this inline in our &lt;code&gt;connect()&lt;/code&gt;. We are taking the state from our store and returning an object that is mapped to props. We are getting a key of quotes from our store state. This key is coming from our &lt;code&gt;rootReducer&lt;/code&gt;, more on this later. TLDR: we are taking the state from our store and mapping it to this component as props. I will also include the way to write it not inline.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;storeState&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;storeState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quotes&lt;/span&gt; &lt;span class="p"&gt;}))(&lt;/span&gt;&lt;span class="nx"&gt;Quotes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// or &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quotes&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;Quotes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our quotes are going to be in array so we are going to have to map them in our &lt;code&gt;render()&lt;/code&gt;. &lt;code&gt;{this.props.quotes.map(q =&amp;gt; &amp;lt;QuoteCard quote={q} /&amp;gt;)}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now to go look at that reducer. What is weird is that&lt;code&gt;rootReducer&lt;/code&gt; has &lt;code&gt;combineReducers&lt;/code&gt; which isn't necessary for this project. But it does link to &lt;code&gt;quotes&lt;/code&gt; and gives us access to our quotes array, so let's take a look at that. This is one of the few things that doesn't have any code really. As with most reducers, let start by making a switch statement. First action is &lt;code&gt;"ADD_QUOTE"&lt;/code&gt; and we want to take the previous state and add to it so this is a great use of the spread operator or you can use &lt;code&gt;.concat&lt;/code&gt; this way we are being non-destructive. You would never want to use &lt;code&gt;.push&lt;/code&gt; as that is destructive and not making a copy. "REMOVE_QUOTE" is our next action. We are going to want to use filter because we want to find the specific quote and delete it. This is where having that &lt;code&gt;uuid()&lt;/code&gt; comes in handy. &lt;/p&gt;

&lt;p&gt;The next two reducers I had no idea where to even start because they have to deal with the upvote and downvote. Votes currently aren't stored in state at all. Let's go back to &lt;code&gt;QuoteForm&lt;/code&gt; as that is where our default state is created. We can assume that votes start at 0 when a quote is created so we can add &lt;code&gt;votes: 0&lt;/code&gt; to our state. Back to our reducers. Remember that from the action, we are just getting back the id of that quote. So we need to &lt;code&gt;find&lt;/code&gt; the quote whose id matches and then increase or decrease the votes. Also remember that this Redux so we don't want to set state here or mutate state. However we only have access to the id so how do we get the whole state of the quote? First let's actually find the index. We want to return the state up to the portion that we are altering so use &lt;code&gt;slice()&lt;/code&gt; with our found index. That will return everything up to this quote, then we want to return the correct quote and then the rest of the state. We still don't really have the quote content so still need to figure that out. Next to find the value of the correct quote. We want to create a new object. We first want to use the spread operator to maintain the state and then pass in the key/value pair we want to change. Then we will do the same for downvotes although keep in mind that we have to make sure the number of votes is positive before we subtract a vote.&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;action&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;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ADD_QUOTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="c1"&gt;// or return state.concat(action.quote)&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REMOVE_QUOTE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;q&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;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quoteId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPVOTE_QUOTE&lt;/span&gt;&lt;span class="dl"&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;quoteIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;q&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;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quoteId&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;quote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;quoteIndex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;votes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;quoteIndex&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;votes&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quoteIndex&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quoteIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DOWNVOTE_QUOTE&lt;/span&gt;&lt;span class="dl"&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;quote&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;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quoteId&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;quoteDown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&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;quoteDown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;votes&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;quoteDown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;votes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;quoteDown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;votes&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&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;Lastly default, you just want to return state. This way something is coming back incase a random action is hit for some reason. &lt;/p&gt;

&lt;p&gt;The last thing is to get everything running in &lt;code&gt;QuoteCard&lt;/code&gt;. So we need to build the quotes and map them better than we previously did. Down and up votes need to be separated so this is where our action creators come back in handy. Let's import them into the &lt;code&gt;Quotes&lt;/code&gt; container so it can be dispatched to the card as props.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;QuoteCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/QuoteCard&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;removeQuote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upvoteQuote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;downvoteQuote&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../actions/quotes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Quotes&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;buildQuotes&lt;/span&gt; &lt;span class="o"&gt;=&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;quote&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;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;QuoteCard&lt;/span&gt; 
        &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;quote&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;quote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nx"&gt;removeQuote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeQuote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;upvoteQuote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upvoteQuote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;downvoteQuote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;downvoteQuote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;hr&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row justify-content-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Quotes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;hr&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;col-md-4&lt;/span&gt;&lt;span class="dl"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buildQuotes&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quotes&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//add arguments to connect as needed&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;removeQuote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;upvoteQuote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;downvoteQuote&lt;/span&gt; &lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;Quotes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can call these dispatch actions on the buttons in &lt;code&gt;QuoteCards&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dotnotation/quote-maker-react-lab"&gt;Here is the link to the repo&lt;/a&gt; if you want to see the entire code. I honestly started writing this when I started up this lab not knowing how long this would take. I apologize that it gets a little rushed at the end but I was running out of time for the day and wanted to be done. Also didn't proofread so please forgive any typing errors. I really struggled with this lab and am still struggling with some of the concepts, but that is what these labs are for. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
    </item>
    <item>
      <title>JS Flatiron Assessment Study Sheet</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Fri, 21 Jan 2022 17:44:05 +0000</pubDate>
      <link>https://forem.com/dotnotation/js-flatiron-assessment-study-sheet-9f2</link>
      <guid>https://forem.com/dotnotation/js-flatiron-assessment-study-sheet-9f2</guid>
      <description>&lt;p&gt;I recently completed and passed my JS assessment at Flatiron. I was a panicked mess before the assessment and was studying so hard. I figured I would give a study sheet of concepts to know and also what to practice for the live coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does the &lt;code&gt;this&lt;/code&gt; keyword mean?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inside a function, this is the object that represents the function's execution context&lt;/li&gt;
&lt;li&gt;in a method it refers to the owner object&lt;/li&gt;
&lt;li&gt;alone and in a function it refers to the global object&lt;/li&gt;
&lt;li&gt;in a function in strict mode it is undefined&lt;/li&gt;
&lt;li&gt;in an event, it refers to the element that received the event&lt;/li&gt;
&lt;li&gt;methods like call, apply, etc can refer this to any object&lt;/li&gt;
&lt;li&gt;returns the current execution context while the function is being run, whether the context was passed explicitly or implicity, this  returns it&lt;/li&gt;
&lt;li&gt;Implicitly set 

&lt;ul&gt;
&lt;li&gt;in bare function calls the context is automatically set to the global object unless prevented by "use strict"&lt;/li&gt;
&lt;li&gt;in non-bare function calls the context is automatically set to the object to the left of the dot&lt;/li&gt;
&lt;li&gt;in OOJS execution context defaults to the new thing being created in a class's constructor &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is destructuring?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;creating variables from objects and arrays&lt;/li&gt;
&lt;li&gt;create objects with same variable name key value pairs&lt;/li&gt;
&lt;li&gt;arrays are destructured with [] and can be set to any variable and has to be in order&lt;/li&gt;
&lt;li&gt;objects are destructured with {} and the variables names need to match the key but can be in any order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;===&lt;/code&gt; ?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;==&lt;/code&gt; loose equality 

&lt;ul&gt;
&lt;li&gt;returns true if the two values are equal but also with type conversion &lt;code&gt;42 == '42' =&amp;gt; true&lt;/code&gt; &lt;code&gt;'0' == false =&amp;gt; true&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;===&lt;/code&gt; strict equality

&lt;ul&gt;
&lt;li&gt;returns true if the two values are equal without performing type conversions &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!=&lt;/code&gt; loose inequality

&lt;ul&gt;
&lt;li&gt;returns true if two values are not equal but also will do type conversion &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!==&lt;/code&gt; strict inequality 

&lt;ul&gt;
&lt;li&gt;returns true if two values are not equal without performing type conversions &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;generally you want to use the strict operators as the loose operators will return true even if the data types aren't the same &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between event capturing and bubbling?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bubbling

&lt;ul&gt;
&lt;li&gt;the event is first captured and handled by the innermost element and then propagated to outer elements&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;capturing

&lt;ul&gt;
&lt;li&gt;the event if first captured by the outermost element and propagated to the inner elements&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is JSON?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS Object Notation&lt;/li&gt;
&lt;li&gt;a string that JS knows how to turn into an object&lt;/li&gt;
&lt;li&gt;serialization format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is DOM and how do you manipulate it?&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document Object Model &lt;/li&gt;
&lt;li&gt;uses JavaScript to:

&lt;ul&gt;
&lt;li&gt;ask the DOM to find or select an HTML element or elements in the rendered page&lt;/li&gt;
&lt;li&gt;remove and/or insert an element&lt;/li&gt;
&lt;li&gt;adjust a property of the selected elements&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;can only be spoken to via JavaScript&lt;/li&gt;
&lt;li&gt;data representation of the objects that comprise the structure and content of a document on the web&lt;/li&gt;
&lt;li&gt;when the DOM is changed, it doesn't change the source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How do you handle events/ How do event listeners work?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;events are something the user does&lt;/li&gt;
&lt;li&gt;3 phases

&lt;ul&gt;
&lt;li&gt;capturing phase- the event goes down to the element&lt;/li&gt;
&lt;li&gt;target phase- the event reached the target element&lt;/li&gt;
&lt;li&gt;bubbling phase- the event bubbles up from the element&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;addEventListener()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;to teach nodes or elements to listen for an event&lt;/li&gt;
&lt;li&gt;allows you to associate hearing an event with executing a callback&lt;/li&gt;
&lt;li&gt;takes two arguments

&lt;ul&gt;
&lt;li&gt;the name of the event&lt;/li&gt;
&lt;li&gt;a callback function to handle the event&lt;/li&gt;
&lt;li&gt;takes a string with the name of the event and a callback function&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt; if you call a function plus () in an event listener, you are actually passing in the return value which is undefined not the function itself

&lt;ul&gt;
&lt;li&gt;if your event automatically fires upon loading instead of the event this is why. Just remove ()&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is fetch and how does it work and what does it return?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is an asynchronous function and doesn't block up our call stack&lt;/li&gt;
&lt;li&gt;all fetch request go first to the web api then to the callback queue and when the call stack is clear, the event loop pushes the fetch request to the call stack&lt;/li&gt;
&lt;li&gt;usually getting a response that you want to put into json so it is readable and then you are also getting the data or the object based on that response&lt;/li&gt;
&lt;li&gt;will only return the promise, you can never make the function return all the data you retrieved from the promise

&lt;ul&gt;
&lt;li&gt;you can access the data until you are in the callback queue&lt;/li&gt;
&lt;li&gt;you can only access the data in an event method&lt;/li&gt;
&lt;li&gt;can only access the data in the then methods&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;because it is an asynchronous method, anything called in that function outside of the fetch, then statements, will run before the fetch method so you can't call anything you declare in the fetch/then methods because they will run after the rest of the block outside of that scope&lt;/li&gt;
&lt;li&gt;a global method on the window object&lt;/li&gt;
&lt;li&gt;pass in a path to a resource as an argument&lt;/li&gt;
&lt;li&gt;to use the data that is returned by fetch, you need to chain on the &lt;code&gt;then()&lt;/code&gt; method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is a Promise? Can you explain how it works in your code?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Promise object represents a value that may not be available yet, but will be resolved at some point in the future. It allows you to write asynchronous code in a more synchronous fashion. For example, if you use the promise API to make an asynchronous call to a remote web service, you will create a Promise object which represents the data that will be returned by the web service in future. The caveat is that the actual data isn’t available yet. It will become available when the request completes and a response comes back from the web service. In the meantime, the Promise object acts like a proxy to the actual data. Furthermore, you can attach callbacks to the Promise object, which will be called once the actual data is available.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why do we use &lt;code&gt;.then&lt;/code&gt; after a fetch request?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;usually getting a response that you want to put into json so it is readable and then you are also getting the data or the object based on that response&lt;/li&gt;
&lt;li&gt;used with &lt;code&gt;fetch()&lt;/code&gt; to help convert the response from fetch&lt;/li&gt;
&lt;li&gt;is chained on the promise from the fetch request but isn't usually explicitly called &lt;code&gt;promise.then()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;takes a function usually with a parameter of response and data&lt;/li&gt;
&lt;li&gt;this is where you tell JS to ask the network response to be turned into JSON&lt;/li&gt;
&lt;li&gt;the second  &lt;code&gt;.then()&lt;/code&gt; is when you actually get some JSON which is the return from the first &lt;code&gt;.then()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;used to get the data from the return of the fetch method which is the promise&lt;/li&gt;
&lt;li&gt;chained on to fetch request to access the data from the promise that is returned &lt;/li&gt;
&lt;li&gt;every &lt;code&gt;.then&lt;/code&gt; returns a new promise&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.then&lt;/code&gt; is a method that you are calling on a promise that's going to take in a callback function and it is going to put that callback right on the callback queue when you get the response back so that when the event loop is empty it is going to call the callback function and pass in the response that you got from the backend from the web api&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Have an understanding of hoisting, scope and context&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scope/lexical scope

&lt;ul&gt;
&lt;li&gt;the only thing that matters is where function and variable are declared which is usually the outer scope&lt;/li&gt;
&lt;li&gt;scope of that variable of a function will have is determined on where it is defined not when it is executed&lt;/li&gt;
&lt;li&gt;with JS it has to do with where declared variables and methods are available within the code&lt;/li&gt;
&lt;li&gt;what functions and variables we have access to&lt;/li&gt;
&lt;li&gt;function scope

&lt;ul&gt;
&lt;li&gt;function from the first curly bracket to the last curly bracket&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;global scope

&lt;ul&gt;
&lt;li&gt;access everywhere&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;block scope

&lt;ul&gt;
&lt;li&gt;only access them within a block &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;for&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt;, or any loop &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;where the variable is defined and how it is defined(&lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, &lt;code&gt;var&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;execution context

&lt;ul&gt;
&lt;li&gt;the 'environment' a function executes in; that is, variable scope (and the scope chain, variables in closures from outer scopes), function arguments, and the value of the this object.&lt;/li&gt;
&lt;li&gt;within it, you can write an expression that references a variable of invokes a function declared in the same context&lt;/li&gt;
&lt;li&gt;creates a new scope that encompasses all of the variables and functions declared in the execution context&lt;/li&gt;
&lt;li&gt;global execution context is the context that implicitly wraps all of the JS code in a project&lt;/li&gt;
&lt;li&gt;variables and functions declared in the global execution context, in the global scope, are accessible everywhere in your JS code&lt;/li&gt;
&lt;li&gt;if a variable or function is not declared inside a function or block it is in the global execution context&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;hoisting

&lt;ul&gt;
&lt;li&gt; refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.&lt;/li&gt;
&lt;li&gt;defines if something is available to be called before it is declared. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;let&lt;/code&gt;  isn't hoisted so you will get a reference error if you use a variable before you declare it  and it can be declared without a value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;const&lt;/code&gt;  isn't hoisted and you will get a reference error if you use the variable before you declare it and the variable must have a value on declaration &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var&lt;/code&gt; gets hoisted and can be declared without a value&lt;/li&gt;
&lt;li&gt;function declarations are hoisted&lt;/li&gt;
&lt;li&gt;arrow functions and function expressions are not hoisted&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is the purpose of the constructor function?&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to set/assign properties to new instances of an object&lt;/li&gt;
&lt;li&gt;the thing you create with the function is a more specific than object  by using the keyword new&lt;/li&gt;
&lt;li&gt;uses &lt;code&gt;this&lt;/code&gt; as the function's context since functions in JS are also objects, a function can say set a property on me&lt;/li&gt;
&lt;li&gt;creates a new copy of itself, leaving the original unchanged and on the copy it is setting the properties based on the arguments passed into the function and the keyword &lt;code&gt;new&lt;/code&gt; tells the constructor to do that&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is a callback function? When do we use them?  Give examples of callback functions in your project.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when you pass a function expression(an anonymous function) or the pointer(variable name, declared function name) to a function as an argument, the passed function is called a callback&lt;/li&gt;
&lt;li&gt;the receiving function of a callback will execute or call that callback function at a later time&lt;/li&gt;
&lt;li&gt;we run some code, give it a callback, and maybe run it later&lt;/li&gt;
&lt;li&gt;functions that are specified as arguments when calling a function which will start executing code in the background

&lt;ul&gt;
&lt;li&gt;an example is the second parameter of the &lt;code&gt;addEventListener()&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;the first parameter is the type of event to be listened for and the second parameter is a callback function that is invoked when the event is fired&lt;/li&gt;
&lt;li&gt;when you pass in the callback function, you are passing in the function's reference as an argument and is not executed immediately&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;most asynchronous functions are passed a callback function&lt;/li&gt;
&lt;li&gt;includes &lt;code&gt;setTimeout()&lt;/code&gt; and &lt;code&gt;fetch()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why do we use serializers?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the process of translating a data structure or object state into a format that can be stored or transmitted and reconstructed later &lt;/li&gt;
&lt;li&gt;In JavaScript, for example, you can serialize an object to a JSON string by calling the function &lt;code&gt;JSON.stringify()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;once in a serialization format, it can be used to create a semantically identical clone of the original object&lt;/li&gt;
&lt;li&gt;serialization of OO objects does not include any of their associated methods with which they were previously linked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is the purpose of &lt;code&gt;JSON.stringify()&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When sending data to a web server, the data has to be a string.&lt;/li&gt;
&lt;li&gt;In JavaScript, for example, you can serialize an object to a JSON string by calling the function &lt;code&gt;JSON.stringify()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are the differences between &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, and &lt;code&gt;var&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Var&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Hoisted&lt;/li&gt;
&lt;li&gt;Function scoped&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Let&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Can change value&lt;/li&gt;
&lt;li&gt;Block scoped&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Const&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t change value&lt;/li&gt;
&lt;li&gt;Block scoped&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What kind of inheritance is JS?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prototypal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Things to practice for live coding&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a form to your DOM, have the input be put on your DOM and return the form to blank&lt;/li&gt;
&lt;li&gt;add a like button that increases a counter&lt;/li&gt;
&lt;li&gt;convert an arrow function to a function declaration and vice versa&lt;/li&gt;
&lt;li&gt;practice array methods like &lt;code&gt;.map()&lt;/code&gt; &lt;code&gt;.filter()&lt;/code&gt; etc. &lt;/li&gt;
&lt;li&gt;be able to look at random code and know &lt;code&gt;this&lt;/code&gt;, hoisting, and scope of variables and functions&lt;/li&gt;
&lt;li&gt;Identify places in your project where the code is running asynchronously and explain what that means.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lastly, good luck! You are going to do great on your assessment. Another tip for the live coding, use &lt;code&gt;console.log()&lt;/code&gt; and &lt;code&gt;debugger&lt;/code&gt; a lot! It shows that you know how to use these and shows that you know how to problem solve. I was told that a lot of people panic and forget to use them and end up freezing up. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Furmiliar: JS Project</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Fri, 14 Jan 2022 23:56:41 +0000</pubDate>
      <link>https://forem.com/dotnotation/furmiliar-js-project-186m</link>
      <guid>https://forem.com/dotnotation/furmiliar-js-project-186m</guid>
      <description>&lt;p&gt;I have finally finished my JavaScript final project for the Flatiron bootcamp. I will say that this project has been by far the most challenging yet. The project had to have a Rails API with a HTML, CSS, and vanilla OO JS frontend. All aspects of processing data had to be done via JS. Trying to do forms and talk with the API was the most important aspect of the project, but most of the course material didn’t cover this at all. I had to watch multiple tutorials to get a grasp on how to approach this. A lot of the labs in this section towards the end were really lacking. I did learn a lot from doing this project but still feel shaky about my knowledge of JS.  With most of my coding adventure so far, the more you learn, the more you realize what you don’t know. &lt;/p&gt;

&lt;p&gt;The use case for my project is an app for pet owners to keep track of toys their pets did and didn’t like. Each pet has a toy box and that toy box contains all the toys for that pet. With the toy boxes and toys, there is full CRUD. The add toy form only pops up when you have opened a toy box so no toys can be added without an associated box. &lt;/p&gt;

&lt;p&gt;A big aspect of this project was to do DOM manipulation on a SPA. Doing this aspect was fun and I tried to mainly use variables as I personally like it more than just rendering everything with &lt;code&gt;.innerHTML&lt;/code&gt;. I did one of my methods with &lt;code&gt;.innerHTML&lt;/code&gt; just to show that I knew how to do it.&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="nx"&gt;addToDom&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;toyBoxDiv&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toy-box&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;toyBoxCard&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toy-box-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-id&lt;/span&gt;&lt;span class="dl"&gt;"&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="k"&gt;this&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;photoBox&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;photoBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;
        &lt;span class="nx"&gt;photoBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toy-box-photo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toyBoxName&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openToyBox&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;createElement&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;openToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Open Toy Box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
        &lt;span class="nx"&gt;openToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`toy-box-button-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&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="nx"&gt;openToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-action&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;open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;openToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openEvent&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;deleteToyBox&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;createElement&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;deleteToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;#10006&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;deleteToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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;toy-box-delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;deleteToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-action&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;delete&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;editToyBox&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;createElement&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;editToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;#9999&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;editToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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;toy-box-edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;editToyBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-action&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;edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;photoBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toyBoxName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;openToyBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteToyBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyBoxCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editToyBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// versus innerHTML&lt;/span&gt;
&lt;span class="nx"&gt;createToyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toyBoxAssociation&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;toyFormContainer&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toy-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyFormContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
        &lt;span class="nx"&gt;toyFormContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline-block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toyForm&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;h2&amp;gt;Add a New Toy&amp;lt;/h2&amp;gt;
            &amp;lt;input type="text" id="toy-photo-input" placeholder="Photo URL"&amp;gt;&amp;amp;emsp;
            &amp;lt;input type="text" id="toy-name-input" placeholder="Name"&amp;gt;&amp;amp;emsp;
            &amp;lt;input type="text" id="toy-brand-input" placeholder="Brand"&amp;gt;&amp;amp;emsp;
            &amp;lt;input type="text" id="toy-price-input" placeholder="Price"&amp;gt;&amp;amp;emsp;
            &amp;lt;input type="text" id="toy-url-input" placeholder="Website URL"&amp;gt;&amp;amp;emsp;
            &amp;lt;input type="text" id="toy-rating-input" placeholder="Rating 1-5"&amp;gt;&amp;amp;emsp;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
            &amp;lt;strong&amp;gt;Needs Repair?&amp;lt;/strong&amp;gt; &amp;lt;input type="radio" id="toy-needs-repair-input-true" name="needs-repair" value="true"&amp;gt;True
            &amp;lt;input type="radio" id="toy-needs-repair-input-false" name="needs-repair" value="false"&amp;gt;False &amp;amp;emsp;
            &amp;lt;strong&amp;gt;Squeaker?&amp;lt;/strong&amp;gt; &amp;lt;input type="radio" id="toy-squeaker-input-true" name="squeaker" value="true"&amp;gt;True
            &amp;lt;input type="radio" id="toy-squeaker-input-false" name="squeaker" value="false"&amp;gt;False &amp;amp;emsp;
            &amp;lt;strong&amp;gt;Crinkle?&amp;lt;/strong&amp;gt; &amp;lt;input type="radio" id="toy-crinkle-input-true" name="crinkle" value="true"&amp;gt;True
            &amp;lt;input type="radio" d="toy-crinkle-input-false" name="crinkle" value="false"&amp;gt;False &amp;amp;emsp;
            &amp;lt;strong&amp;gt;Hides Treats?&amp;lt;/strong&amp;gt; &amp;lt;input type="radio" id="toy-treat-input" name="treat" value="true"&amp;gt;True
            &amp;lt;input type="radio" name="treat" value="false"&amp;gt;False &amp;amp;emsp;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;`&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addToyBoxId&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;addToyBoxId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;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;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;addToyBoxId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;toy-box-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;addToyBoxId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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;toy-box-id-input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;addToyBoxId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;toyBoxAssociation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&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;createElement&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;submit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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;toy-submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;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;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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;Add Toy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Add Toy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

        &lt;span class="nx"&gt;toyForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;addToyBoxId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;toyFormContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toyForm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;toyForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toySubmit&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;One thing that really tripped me up on my project was in my fetch requests I was initially told that since I had a nested array of attributes that I needed to use dot notation on the data I was receiving to access it. I asked several people to figure out what was going on and the third person I asked was finally able to help me. It was odd because in debugger the response was just CORS, which made no sense to anyone and I am still puzzled why calling &lt;code&gt;data.toys&lt;/code&gt; instead of &lt;code&gt;data&lt;/code&gt; would return CORS.  &lt;/p&gt;

&lt;p&gt;Another thing that I struggled with were the radio buttons. I had a hard time finding good documentation on vanilla JS handling radio buttons. Handling radio buttons with Rails was so easy and JS proved to be a lot more challenging. That is one aspect I one day want to revisit is fixing my radio buttons. I really wanted for when you edit a toy, the radio buttons are filled in with the information from the API. I couldn’t find an elegant solution that was DRY. &lt;/p&gt;

&lt;p&gt;I found it helpful to go through my code and console log every function as it was hit. I figured I would provide that breakdown as well. I broke down each action and stated the class that each method is from and the method name. The classes I have are toyBoxAdapter and toyAdapter which deal with the fetch requests for those objects, toy and toyBox, and toyForm and toyBoxForm for the forms associated with those classes. You can view all of my code &lt;a href="https://github.com/dotnotation/Furmiliar_Frontend"&gt;on my github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;upon initial load&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DOMContent Loaded&lt;/li&gt;
&lt;li&gt;toyBoxAdapter fetchToyBoxes&lt;/li&gt;
&lt;li&gt;toyBoxForm createToyBoxForm&lt;/li&gt;
&lt;li&gt;toyBoxForm listenEvents&lt;/li&gt;
&lt;li&gt;toyForm listenToys&lt;/li&gt;
&lt;li&gt;toyBox addToDom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;creating a toyBox&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyBoxForm handleSubmit&lt;/li&gt;
&lt;li&gt;toyBoxAdapter createToyBox&lt;/li&gt;
&lt;li&gt;toyBox addtoDom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;editing toyBox&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyBoxForm handleEvents&lt;/li&gt;
&lt;li&gt;toyBoxForm handleSubmit&lt;/li&gt;
&lt;li&gt;toyBoxAdapter editToyBoxes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;deleting toyBox&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyBoxForm handleEvents&lt;/li&gt;
&lt;li&gt;toyBoxAdapter deleteToyBox&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;open toyBox&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyBox openEvent&lt;/li&gt;
&lt;li&gt;toyBox getToys&lt;/li&gt;
&lt;li&gt;toy renderToys&lt;/li&gt;
&lt;li&gt;toyForm createToyForm&lt;/li&gt;
&lt;li&gt;toyBoxForm handleEvents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;add toy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyForm toySubmit&lt;/li&gt;
&lt;li&gt;toyAdapter createToy&lt;/li&gt;
&lt;li&gt;toy renderToys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;edit toy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyForm toyEvents&lt;/li&gt;
&lt;li&gt;toyForm toySubmit&lt;/li&gt;
&lt;li&gt;toyAdapter editToy&lt;/li&gt;
&lt;li&gt;toyForm toySubmit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;delete toy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;toyForm toyEvents&lt;/li&gt;
&lt;li&gt;toyAdapter deleteToy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested in the &lt;a href="https://github.com/dotnotation/Furmiliar_Backend"&gt;backend&lt;/a&gt; of my app. I just used &lt;code&gt;rails new project_name --api&lt;/code&gt; to create the backend of my app and kept most things the same from the auto-generated code. &lt;/p&gt;

&lt;p&gt;Now with this project wrapped, I have to prepare for the assessment. I have been studying and practicing but still feel unprepared. I think I will just have to schedule the assessment and see how it goes. I have heard that this assessment is one of the most challenging. Wish me luck!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>rails</category>
    </item>
    <item>
      <title>My First Time Using JS</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Thu, 04 Nov 2021 16:51:25 +0000</pubDate>
      <link>https://forem.com/dotnotation/my-first-time-using-js-5506</link>
      <guid>https://forem.com/dotnotation/my-first-time-using-js-5506</guid>
      <description>&lt;p&gt;This week I started learning JS in my Flatiron bootcamp. This is the language I was most excited to learn. It is definitely more challenging than I anticipated and I still have very basic questions about so many aspects of the language. For instance, semicolons, when to use them? The arrow function expressions are still really muddy for me. Division of concerns is not as clear to me in JS as it was in Ruby. It is only my first week so I am giving myself some room to struggle. &lt;/p&gt;

&lt;p&gt;Most of the labs this week were basically code alongs with no real substance. They were very helpful for me, but overall not that interesting. I wanted to share my first real lab in the JS course which is called Task Lister Lite. The point of the lab is to use &lt;code&gt;.preventDefault()&lt;/code&gt; so that every time someone submits a new task to the list, the page doesn't refresh. Bonus points for doing anything else. I decided to also add an edit and delete buttons as well. This is purely front end so none of the information is persisted to a database of any sorts. &lt;/p&gt;

&lt;p&gt;Instead of doing my usual explanations, I have decided to just share all of the pseudo code I did. Since I am so new to the language, I wrote so much pseudo code that I think is more helpful than me describing every aspect. Anyways I hope you enjoy my first JS project.&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;let&lt;/span&gt; &lt;span class="nx"&gt;editMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&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="o"&gt;=&amp;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;taskForm&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;create-task-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// grab form&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskForm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;taskForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// add event listener for submit and handling submit&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// prevent the default so the page won't reload&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;taskInput&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-task-description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// grab input field&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;editMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;editMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taskInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="c1"&gt;// edit the children of the individual task and the first child is the text&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit-task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Create New Task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// resetting the submit button to say Create New Task again&lt;/span&gt;
    &lt;span class="nx"&gt;editMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// ending edit mode&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;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// add the value of the input to the task list&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;taskInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="c1"&gt;// resetting the input field text&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&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;tasksDiv&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// grab the tasks div&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskDiv&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// create a new div for each task&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskSpan&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// create a span for each task&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteIcon&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// create 'x' element for deletion &lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;editButton&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// create edit button&lt;/span&gt;

  &lt;span class="nx"&gt;deleteIcon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;#10006;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// making delete icon look like an x&lt;/span&gt;
  &lt;span class="nx"&gt;taskSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// add the text to the task span&lt;/span&gt;
  &lt;span class="nx"&gt;editButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;deleteIcon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="nx"&gt;event&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="nx"&gt;event&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;parentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;//grabbing the parent element of the delete icon (taskDiv) and deleting it&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;editButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleEdit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;taskDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskSpan&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteIcon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;editButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// add the task span, delete icon, and edit button to the individual task div&lt;/span&gt;
  &lt;span class="nx"&gt;tasksDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskDiv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// add the individual task divs to the div container&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleEdit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;taskDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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;parentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// grabbing the parent to the individual task div&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taskDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// grab the individual task div&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submitButton&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit-task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// grab submit button&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-task-description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// get the text input&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// change the value of the text input to the comment we are editing&lt;/span&gt;
  &lt;span class="nx"&gt;submitButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// change the submit button to say Edit&lt;/span&gt;
  &lt;span class="nx"&gt;editMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taskDiv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// edit the individual task div&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Bat Cloud: A Rails Project</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Wed, 13 Oct 2021 18:36:12 +0000</pubDate>
      <link>https://forem.com/dotnotation/bat-cloud-a-rails-project-5c43</link>
      <guid>https://forem.com/dotnotation/bat-cloud-a-rails-project-5c43</guid>
      <description>&lt;p&gt;Today I finished my Ruby on Rails project which is my third final project for my Flatiron bootcamp. If you read my last blog, the concept of this project will be very familiar. I decided to redo my bat researchers’ log web application. With the power of Rails and learning new concepts, I knew I could make the original project even better. I did decide to rename the app Bat Cloud as it sounded better and a group of bats is sometimes called a cloud. If you didn’t read my last blog, I would recommend you do so, it is a quick read, and you can see the improvements. &lt;/p&gt;

&lt;p&gt;The main things I updated were a notes field, the associations, and a few new views and options. The note field update was partly to do with the fact that I had to have a many to many relationship. The associations between my models this time are as follows. Researchers have many notes, have many bats through notes, and have many discovered bats through a foreign key that associates a discovered bat to that researcher. Notes belong to a Researcher and a bat. Bats have many notes, have many researchers through notes, and belong to a discoverer (the researcher who created the bat entry). The new views include all researchers, and recently discovered bats which utilizes a scope method to sort the bats by date found. Another major improvement I made was adding a search field where a researcher can search by the bat tag number. I also implemented Omniauth so someone can log in via Google. I of course would like to add more features in the future, but I am happy with where this project is currently. &lt;/p&gt;

&lt;p&gt;I wanted to go over some of the challenges I faced with this project. I definitely struggled with my associations in the beginning and made things a lot more complicated than they needed to be. I originally wanted to have a separate model of an organization that would be the admin. After talking to my cohort lead, he said that he wouldn’t recommend going down that path at this point in time. Instead he suggested giving roles to certain researchers/users. This is what I ended up doing. Each researcher can either be an admin or a member. Any admin can change the access of any member. This of course isn’t the best method and I would like to improve this in the future. I originally tried to put an organization_id foreign key to associate a member with an organization but I realized that I really needed a separate model for organization to make this work. The other issue I faced with my associations was trying to have the bat belong to the researcher and the note, instead of having the note belong to the researcher and the bat. My cohort lead also brought up a good point about how many researchers could be taking notes on one bat. He also suggested having a foreign key that would associate a bat to the person who discovered the bat, which led to me adding the association of researchers having many discovered bats and a bat belonging to a discoverer through the discoverer_id that is a hidden field when you create a bat. Although I realized late in my project that my partial form for edit and new had the hidden field of discoverer_id so when someone edited a bat, they would become the discoverer. Also had to add a bunch of conditionals in case that researcher's account was deleted. I ended up figuring out my associations thanks to the help of my cohort lead. I am glad I talked things out with him before really starting to code. I see so many other students show up with bad associations and a finished project and having so many issues based on their associations. I wanted to make sure I took the time to nail those before getting too far.  &lt;/p&gt;

&lt;p&gt;Another thing I really struggled with was converting all of my time stamps/datetime into something readable. Since I have so many fields that were time stamps/datetime, it seemed ridiculous to write out strftime methods for all of them. I did a bunch of googling and liked the solution from &lt;a href="https://stackoverflow.com/questions/22255476/rails-formatting-date"&gt;stack overflow&lt;/a&gt; the best. The steps listed were: Create an initializer for it:&lt;br&gt;
&lt;code&gt;config/initializers/time_formats.rb&lt;/code&gt; &lt;br&gt;
Add something like this to it:&lt;br&gt;
&lt;code&gt;Time::DATE_FORMATS[:custom_datetime] = "%d.%m.%Y"&lt;/code&gt;&lt;br&gt;
And then use it the following way:&lt;br&gt;
&lt;code&gt;post.updated_at.to_s(:custom_datetime)&lt;/code&gt;&lt;br&gt;
The code I put in my &lt;code&gt;time_formats.rb&lt;/code&gt; was &lt;code&gt;Time::DATE_FORMATS[:custom_datetime] = "%B %d, %Y at %I:%M %P"&lt;/code&gt; &lt;br&gt;
In the show page: &lt;code&gt;@bat.updated_at.to_s(:custom_datetime)&lt;/code&gt;. This worked out great and then when the researcher looks at a bat’s show page all the dates are read as “October 05, 2021 at 12:00 am.” which is more readable than the UTC. I also found out about the datetime_select field on form helpers. This made it a lot easier for someone to enter the date and time in a universal format that would be easy to put in the database without error. Before when people were testing my app, they would often enter something invalid by switching the date and month as the entry wasn’t intuitive before. I am not sure if this was the best solution to my dates problem but it does work. It isn’t as dry as I would like it to be. If anyone has a better solution, please let me know. &lt;/p&gt;

&lt;p&gt;While I have been enjoying this bootcamp, I will say that a part of this section that was really lacking was the section on OmniAuth. The two labs that dealt with it, didn’t have you do anything with the information you were given from the third party. It would check that you were able to sign in, but not how to process that information in your own database. I was left scratching my head on what to do with it. For instance, they didn’t mention anything about the uid. They also didn’t tell you how to deal with multiple third parties. Granted there are videos and plenty of information to find out about all this on your own, but I expected them to give a little more on this very important topic. Also a problem I have noticed when I sign in with a provider is that a lot of websites want you to enter a password to delete your account, and your provider password doesn’t work, so I am always at a loss of what to do in those situations. I ended up using Google as my provider for this project as it is how I like to sign in to most websites. I thought it was cool that Google, and Github offer icons for you to use as a developer! I liked that Github even had light and dark options. &lt;/p&gt;

&lt;p&gt;Here is my OmniAuth method:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;omniauth&lt;/span&gt;
       &lt;span class="vi"&gt;@researcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Researcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;])&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;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:email&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="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:info&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="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:uid&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="nf"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:provider&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="nf"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;

       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@researcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid?&lt;/span&gt;
           &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:researcher_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@researcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;
           &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;bats_path&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:danger&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@researcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
           &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;login_path&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;      
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I do want to keep working on this app. In the future, I want to add password reset, a more secure admin function, the ability to edit and delete field notes, more static pages, and more styling. However it is more important to continue with my bootcamp than work on this project forever. Especially working full time again, I need to keep making progress so I can graduate from this bootcamp and fully switch into my new career path.   &lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Bat Researchers' Log MVC Sinatra</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Wed, 18 Aug 2021 19:31:09 +0000</pubDate>
      <link>https://forem.com/dotnotation/bat-researchers-log-mvc-sinatra-10kf</link>
      <guid>https://forem.com/dotnotation/bat-researchers-log-mvc-sinatra-10kf</guid>
      <description>&lt;p&gt;Today I finished my MVC Sinatra project for Flatiron School. I am happy to share with you my Bat Researchers’ Log, which is my first web application.  The goal of this application is to help researchers from all over the world to communicate about the bats that they are researching.&lt;/p&gt;

&lt;p&gt;I first wanted to say how much I loved learning Sinatra. Before this section of Flatiron, everything was CLI which was cool but not as rewarding as seeing something on the internet that I created, although just ran from my localhost. I even got to do my own CSS and HTML styling which was incredible. I did use Bootstrap for a lot of my styling, but definitely made it my own. &lt;/p&gt;

&lt;p&gt;MVC stands for Models, Views, and Controllers. Views are what the user sees when they open up a web application. The views are written in .erb files which stands for embedded Ruby. This allows you to add ruby into your HTML. For instance, I often used erb tags to add if statements or to auto generate attributes of a certain bat so you don’t have to hard code in each individual bat. Here is an example from my user show page or account page:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= @user.username %&amp;gt;&amp;lt;/h3&amp;gt;
Email: &amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="no"&gt;Organization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= @user.organization %&amp;gt;&amp;lt;br&amp;gt;
Bats:
   &amp;lt;ol&amp;gt;
       &amp;lt;% @user.bats.all.each do |bat| %&amp;gt;
           &amp;lt;li&amp;gt;&amp;lt;a class=&lt;/span&gt;&lt;span class="s2"&gt;"button"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/bats/&amp;lt;%= bat.identification %&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= bat.identification %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
       &amp;lt;% end %&amp;gt;
   &amp;lt;/ol&amp;gt;

&amp;lt;% if logged_in? &amp;amp;&amp;amp; current_user.id =&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
   &amp;lt;a class="btn btn-warning btn-sm active" href="/user/&amp;lt;%= @user.slug %&amp;gt;&lt;/span&gt;&lt;span class="sr"&gt;/edit"&amp;gt;Edit Your Account&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"btn btn-danger btn-sm active"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/user/&amp;lt;%= @user.slug %&amp;gt;/delete"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;Delete&lt;/span&gt; &lt;span class="no"&gt;Your&lt;/span&gt; &lt;span class="no"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The erb tags are &lt;code&gt;&amp;lt;% %&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;%= %&amp;gt;&lt;/code&gt;. If the logic isn’t something that will be shown on the page, you will use &lt;code&gt;&amp;lt;% %&amp;gt;&lt;/code&gt;. Otherwise you use &lt;code&gt;&amp;lt;%= %&amp;gt;&lt;/code&gt; to display specific information to the user. The views allow the user to communicate through HTTP requests to our controllers.&lt;/p&gt;

&lt;p&gt;The controllers relay data from the browser to the application and from the application to the browser. The controller takes requests from the views and then talks to the models. The controller takes requests that are associated with what the user sees as urls. For example my most basic controller function is to load the welcome page, which looks like:&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;get&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="n"&gt;erb&lt;/span&gt; &lt;span class="ss"&gt;:welcome&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is just saying if the request is to get the root then load the view welcome. Basically just loading the home page of my application. If you wanted to save new data, for instance when a new user creates an account, then that would be a post request. We are saving, or posting data to our database.&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;post&lt;/span&gt; &lt;span class="s1"&gt;'/signup'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
       &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&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;:user&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
       &lt;span class="c1"&gt;#binding.pry&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;
           &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/bats"&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/signup"&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we are editing an existing entry in our database, then that would be a patch request.&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="s1"&gt;'/bats/:identification'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
       &lt;span class="n"&gt;bat_authorization&lt;/span&gt;
       &lt;span class="c1"&gt;#binding.pry&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@bat&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="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:bat&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Your bat has been updated."&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/bats/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@bat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;identification&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@bat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/bats/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@bat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;identification&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/edit"&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: to use patch or delete, you must &lt;code&gt;use Rack::MethodOverride&lt;/code&gt; which you add that line of code to config.ru with your other controllers. It must be at the top of the list of your controllers, otherwise it won't work.&lt;/p&gt;

&lt;p&gt;The models are where data is manipulated and or saved. It connects to our database to create new instances of a class. Basically every time you make a new bat or a new user, that is the job of the model. The model sets the attributes, relationships, and validates aspects as each new bat or user is created. In my case, I have two models, bats and users.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
   &lt;span class="n"&gt;has_secure_password&lt;/span&gt;

   &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:bats&lt;/span&gt;

   &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uniqueness: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;length: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;minimum: &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;presence: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;uniqueness: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;format: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="no"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MailTo&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EMAIL_REGEXP&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="c1"&gt;# /\A[a-zA-Z0-9.!\#$%&amp;amp;'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/&lt;/span&gt;
   &lt;span class="n"&gt;validates&lt;/span&gt; &lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;length: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;in: &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;slug&lt;/span&gt;
       &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&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="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_slug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&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="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;has_many&lt;/code&gt; line creates an association between the two models. The user has many bats and a bat belongs to a user. Using ActiveRecord validations, I am making sure that the user has a secure password that is between 6-20 characters. I am also making sure that the username is unique so there won’t be multiples of one user and that the length of the username is 5 characters. In the email validations I am also making sure that the email is unique and follows basic email format by using &lt;code&gt;format: {{with: URI::MailTo::EMAIL_REGEXP}&lt;br&gt;
&lt;/code&gt;. It uses regex to do a basic checking of alphanumeric characters, an @ symbol, and the like. In the notes below that validation I wrote out the long version of that regex. I also wanted to make sure that the url for each user was their username instead of the &lt;code&gt;user_id&lt;/code&gt;, so I put my slug methods here.&lt;/p&gt;

&lt;p&gt;On the topic of validations, I also used rack flash for my error messages. To use rack flash, in your gemfile add &lt;code&gt;gem 'rack-flash3', '~&amp;gt;1.0'&lt;/code&gt;, in your environment file add require 'rack-flash', and in your application controller configure statement add &lt;code&gt;use Rack::Flash, :sweep =&amp;gt; true&lt;/code&gt;. I added the flash messages in a lot of my controllers. Here is one example:&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="s1"&gt;'/user/:slug'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
       &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_slug&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;:slug&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

       &lt;span class="n"&gt;user&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="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
       &lt;span class="c1"&gt;#binding.pry&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Your account has been updated."&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/user/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
       &lt;span class="k"&gt;else&lt;/span&gt;
           &lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;full_messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
           &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s2"&gt;"/user/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/edit"&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to have success messages which are my &lt;code&gt;flash[:message]&lt;/code&gt; and error messages &lt;code&gt;flash[:error]&lt;/code&gt;. In the above example if the user account is updated a message will flash saying “Your account has been updated.” If there was a problem with the update, then the error message based on that specific error will flash. In this case it would most likely be about the format of the email, the password length, or an already existing username. In my layout.erb file I added:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% if &lt;/span&gt;&lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"alert"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= flash[:error] %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;% end %&amp;gt;

 &amp;lt;% if flash[:message] %&amp;gt;
   &amp;lt;div class=&lt;/span&gt;&lt;span class="s2"&gt;"alert alert-success"&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"alert"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= flash[:message] %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;% end %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;​​I wanted messages with a color background so they are very obvious, but if you don’t add the if statements, the color band will always show. My repo can be viewed &lt;a href="https://github.com/dotnotation/Bat_Researchers_Log"&gt;here&lt;/a&gt;. I would love any feedback on this app. My app is very simple but I am happy with how my first attempt at an app turned out. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>webdev</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>Hairless Furever: My First CLI Gem</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Mon, 21 Jun 2021 21:25:40 +0000</pubDate>
      <link>https://forem.com/dotnotation/hairless-furever-my-first-cli-gem-5cab</link>
      <guid>https://forem.com/dotnotation/hairless-furever-my-first-cli-gem-5cab</guid>
      <description>&lt;p&gt;I have finally made it to my final project in Ruby. The task is to create a CLI gem which you have to create from scratch. I was terrified at the prospect of having to create something from nothing. I am so used to having test suites and all of the files created for me. When I was reading the directions it said we have to have a license, and my first thought was, “How do you go about licensing? What if I can’t figure out one of the first steps?” However I learned it isn’t so scary to create from scratch as long as you use the &lt;code&gt;bundle gem&lt;/code&gt;. This magical tool creates all of the files I am used to having handed to me. Already my README, license, rakefile, etc. pop up like magic. &lt;/p&gt;

&lt;p&gt;While &lt;code&gt;bundle gem&lt;/code&gt; was a cool thing to learn about, it wasn’t my first step. I first planned out my app and made sure the website I wanted to use was scrapable. I decided to make an app all about hairless dogs. I have been obsessed with hairless dogs almost my whole life. Information about them isn’t readily available and is rarely in one place. When I was searching for hairless breeds, only two websites had all of the breeds listed. Even the Wikipedia article and the AKC had two to four breeds listed. I wanted to create a simple gem that I was passionate about. Also the dog in the cover image is my puppy named Momo who is a Chinese Crested. I used a &lt;a href="https://replit.com/@TheGingertonic/ScraperChecker" rel="noopener noreferrer"&gt;scraper checker replit&lt;/a&gt; to make sure the information I wanted to gather was indeed scrapeable. I then followed the advice to create a flowchart and write about how this app will work. This also told me how many classes I would need. These classes would be CLI, Dog, and Scraper. I decided I wanted people to choose from a list of hairless dogs and then show them more information about each breed including description, height, weight, and physical characteristics. I was hoping to gather some more information, but not all of the breeds had a lot more information.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjg4ig02h5h2144k5in9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjg4ig02h5h2144k5in9.png" alt="Flowchart of how Hairless Furever the CLI gem will work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that all of the planning was done, it was time to finally run &lt;code&gt;bundle gem hairless_furever&lt;/code&gt;. “Hairless Furever” is what I decided to name the app. This would allow for expansion of other types of hairless critters like cats, guinea pigs, etc. &lt;/p&gt;

&lt;p&gt;I wanted to set up my git and repo so everything would be stored. I learned that the gitignore file doesn’t push the files listed into the repo. I created a repo on GitHub and then connected all my files to the magical cloud. Then I created and changed the permissions on my &lt;code&gt;./bin/hairless_furever&lt;/code&gt; so that the file would be executable by &lt;code&gt;chmod +x hairless_furever&lt;/code&gt;. This file also needed the shbang &lt;code&gt;#!/usr/bin/env ruby&lt;/code&gt; to be added so the program would know what language to use. I also added a puts statement so I could tell when things were running properly. I made sure that the class CLI had a namespace name so it would be easy to distinguish when someone is using the app and being able to differentiate from other apps. For example, there are probably tons of already existing gems with a class of CLI, Dog, and Scraper. I needed to make sure that my gem could easily interact with other gems with similar class names. &lt;/p&gt;

&lt;p&gt;The next task at hand was to make sure I had access to other gems. Since I need to understand what my code is doing, pry is a must. Nokogiri and open uri are essential to the scraping I will need to do. Then the classic bundler and rake also needed to be available. I popped all of that into my gemspec file and after a bit of trial and error, everything was working. I had an executable file that was able to run a class that I made, and my scraping and debugging tool. &lt;/p&gt;

&lt;p&gt;I wanted to start stubbing out my CLI so I can have the base of the user interaction figured out before I started scraping anything. Stubbing is when you put in fake data just to see how things were running. For instance instead of trying to scrape a website to get the list of dogs, I just hardcoded in an array of the dog breeds. I started with just commenting in the steps of a welcome message, get the list of breeds, get the user input, show them a dog, and allow them to leave the program. I also realized I needed to make sure that the input would be valid and that the program would loop. All the information I was using to create this was not the real data but I just wanted the bare bones to build off of so I could better test and troubleshoot as I went. &lt;/p&gt;

&lt;p&gt;I created the Dog class with the general initialize, &lt;code&gt;@@all&lt;/code&gt; array, &lt;code&gt;save&lt;/code&gt;, &lt;code&gt;self.all&lt;/code&gt; methods. At this point I only added the &lt;code&gt;attr_accessor&lt;/code&gt; of name, as I wasn’t quite sure what else I would need at this point, and I wasn’t going to start scraping for other content until I got the breed list figured out. Note: I did eventually change my &lt;code&gt;attr_accessor&lt;/code&gt; to a &lt;code&gt;attr_reader&lt;/code&gt; as I didn't need my Dog class to write any of this data as my scraper class would be doing the writing. &lt;/p&gt;

&lt;p&gt;Now was the time to start scraping. I created my DogCatcher class and used the information I had gathered earlier from the replit of the scraper checker. I ran into a silly mistake of calling my Dog.new outside of my each loop and I kept getting a return of an instance of the class object instead of my list when I ran my program. After doing a little digging, I moved this inside the loop and everything was running again. I started creating other attributes for each dog like description, weight, height, and physical characteristics. I wanted every dog object instance to have all of these attributes assigned to it. However, I ran into more issues with my scraping method. First issue was that everything I was scraping was being stored into one instance. All ten dog breeds, and all of their attributes were in one instance of the dog class. The next issue was that I had nested paragraphs that had no unique identifiers that I wanted to get information from and I couldn’t figure out how to separate the data. I tried calling the children method, but that kept getting a no method error and the index was returning just one piece of information, not looping. At this point, I was feeling really defeated. I felt like I completely broke my program. Something that was working the way I wanted to, was now either not running, not returning information, or not returning the correct information. In the meantime, I decided to add an ASCII dog to the end of my program to lift my spirits. I wasn’t able to find the author of the ASCII unfortunately. I also ran into an issue with my &lt;code&gt;\&lt;/code&gt; just not showing up. After some googling, I found out that if I put two in a row, only one would show up and solve the problem. Not sure if that is the best solution but it worked. With my methods seeming broken, I commented almost everything out and decided to try a new approach of storing my information into an array. After trying that, I ran into the same problems, so there is still something wrong with my scraping method and not with what I originally wrote. I went back to my original code because it is more object oriented, the whole point of this project and it was also easier to read. I also found someone elses project that used a similar method to what I was doing, and theirs worked, so it gave me hope to continue. &lt;/p&gt;

&lt;p&gt;I decided to watch some tutorials and I at least solved one of the issues I was having. The issue was with the nested paragraphs with no unique identifiers that I needed to scrape information from. I had previously tried children and calling an index on it, but neither one of those worked. In one of the videos I was watching, I saw them add &lt;code&gt;:first&lt;/code&gt; into the css selector itself! I was previously calling it outside of the selector. For example I was first trying &lt;code&gt;height = breed.css(".comp.mntl-sc-block-callout-body p").first.text&lt;/code&gt; instead of &lt;code&gt;height = breed.css(".comp.mntl-sc-block-callout-body p:first").text&lt;/code&gt;. I used this also to do &lt;code&gt;:last&lt;/code&gt; and the one that took awhile to find &lt;code&gt;:nth-child(2)&lt;/code&gt;. Here is a great &lt;a href="https://www.w3schools.com/cssref/css_selectors.asp" rel="noopener noreferrer"&gt;guide&lt;/a&gt; to the selectors. Finally I had those tricky selectors figured out. Speaking of selectors, I got help from my section lead on why all of my information was getting shoveled into one instance of the Dog class. I showed him my screen recording of when I originally had it working, and he noticed that I forgot to add &lt;code&gt;li&lt;/code&gt; to my selector. Basically what was happening was that since my selector up one level from where it needed to be, it was treating the whole section as one, instead of seeing each &lt;code&gt;li&lt;/code&gt; element. I knew it was going to be something silly that I was overlooking. We added that to my code, and ta da! Everything was working. He also looked at my code and said it was good enough to turn in! I was so relieved. &lt;/p&gt;

&lt;p&gt;As difficult as this project was, I learned a lot. It also wasn’t as scary as I originally thought. It was fascinating to learn how easy it was to create a gem with bundler. It was great to challenge myself with figuring out the css selectors. I learned how to select with children which was something I read about but never put into practice before. These selectors I also clearly misunderstood before. This is why doing is always so important. It is one thing to read it but another to actually implement it. Since I had For anyone else who is doing this project, I do want to say be patient, watch all of the videos, and don’t be hard on yourself. I would also say to keep it simple. As someone with no previous coding experience, I did something very simple. The great thing about this is that you can expand it. I started just with stubbing everything out, then just getting the name to work and then adding on from there. If I would have put too much in at once, it would have been harder to troubleshoot and debug. I also tried to keep every method simple. No method should be trying to do too much. I noticed with a lot of the refactoring videos I watched, most of them were separating things into smaller methods and also not repeating yourself too much. Here a &lt;a href="https://youtu.be/CwMR3lTrmoc" rel="noopener noreferrer"&gt;video&lt;/a&gt; of me walking through my code. &lt;/p&gt;

&lt;p&gt;Here is an explanation of how my code works. The CLI class starts with the call method, which calls on the scraper class, named DogCatcher. The DogCatcher class scrapes my website for name, description, height, weight, and physical characteristics using Nokogiri and open uri. Each instance is saved to my Dog class using the &lt;code&gt;find_or_create_by_name&lt;/code&gt; method which takes in an argument of all of the attributes mentioned. With the scraping done, the program goes back to the CLI class. Here the CLI class welcomes the user. Next the program has a flow loop that until the user input is "exit" the program will continue to run in a loop of fetched_dogs, and fetch_user_dog which have other methods that they call on that also add to the looping ability of my program. If the user chooses exit, then the &lt;code&gt;farewell&lt;/code&gt; method runs and the program ends.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HairlessFurever::CLI&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
        &lt;span class="c1"&gt;#start scraping method&lt;/span&gt;
        &lt;span class="no"&gt;HairlessFurever&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DogCatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;catch_dog_breeds&lt;/span&gt;
        &lt;span class="c1"&gt;#welcome user and set flow of program&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Welcome to Hairless Furever!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Here you can learn all about hairless dog breeds.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"U・ᴥ・U"&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;" u u"&lt;/span&gt;
        &lt;span class="vi"&gt;@input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
        &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="vi"&gt;@input&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"exit"&lt;/span&gt;
            &lt;span class="n"&gt;fetched_dogs&lt;/span&gt;
            &lt;span class="n"&gt;fetch_user_dog&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="n"&gt;farewell&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# we will get back to the rest of the CLI in a bit&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HairlessFurever::DogCatcher&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;catch_dog_breeds&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Nokogiri&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://www.thesprucepets.com/hairless-dog-breeds-4801015"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ul#sc-list_1-0 li"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&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;breed&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 

            &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".mntl-sc-block-heading"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"p.comp.text-passage"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
            &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".comp.mntl-sc-block-callout-body p:first"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
            &lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".comp.mntl-sc-block-callout-body p:nth-child(2)"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt; 
            &lt;span class="n"&gt;physical_characteristics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".comp.mntl-sc-block-callout-body p:last"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;

            &lt;span class="no"&gt;HairlessFurever&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned the first thing in the loop of the CLI is &lt;code&gt;fetched_dogs&lt;/code&gt;. This method calls on the Dog class and grabs all the dogs and stores each into an instance variable. It then asks the user which dog they would like information on. The instance variable of dogs is then called on. I used &lt;code&gt;.each.with_index(1)&lt;/code&gt; as opposed to &lt;code&gt;each_with_index&lt;/code&gt;. When you use &lt;code&gt;.each.with_index(argument)&lt;/code&gt; it takes in an argument and you can tell it to start the indexing at 1 instead of the default 0 that &lt;code&gt;each_with_index&lt;/code&gt; would do. This starts a loop that puts out each dog name with its respective index.&lt;/p&gt;

&lt;p&gt;Since I mentioned &lt;code&gt;Dog.all&lt;/code&gt; let's jump into my Dog class. As previously mentioned, the Dog class has all &lt;code&gt;attr_reader&lt;/code&gt; of the variables, since the DogCatcher class is doing the writing. Next is the class variable &lt;code&gt;@@all&lt;/code&gt; which is set to an empty array. Why I am using a class variable is so it is accessible across all of the methods in my Dog class. I of course have the classic initialize method which reads all of my &lt;code&gt;attr_reader&lt;/code&gt; variables. I have a save method instead of doing the shoveling into the array in the initialize method since we don't always want to save upon initialize. I also have a better method in place. Next is the class method of &lt;code&gt;self.all&lt;/code&gt; which reads the &lt;code&gt;@@all&lt;/code&gt; array which is what we are using to generate our list in the CLI fetched_dogs method. I think I have mentioned this previously in another post, but something I learned was to keep methods short and concise. You don't want one method doing too much. Having methods that do a single thing is more flexible and allows more room to build out your app. First up in that realm is the class method of &lt;code&gt;self.create&lt;/code&gt; this method not only initializes an instance of the Dog class taking in all of the attributes of the dog, it also saves these into the &lt;code&gt;@@all&lt;/code&gt; array by calling on the &lt;code&gt;save&lt;/code&gt; method. Next is the &lt;code&gt;find_by_name(name)&lt;/code&gt; method. This method makes sure that I don't have duplicate entries in my &lt;code&gt;@@all&lt;/code&gt; array by using detect. Finally the previously mentioned &lt;code&gt;find_or_create_by_name&lt;/code&gt; method. This method was called upon in the DogCatcher method to create instances of my Dog class. The great thing is that I call upon both my &lt;code&gt;find_by_name&lt;/code&gt; and &lt;code&gt;create&lt;/code&gt; methods. If the dog name is not found by &lt;code&gt;find_by_name&lt;/code&gt; then that dog is created using the &lt;code&gt;create&lt;/code&gt; method.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HairlessFurever::CLI&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetched_dogs&lt;/span&gt;
        &lt;span class="c1"&gt;#getting all the dog breeds&lt;/span&gt;
        &lt;span class="vi"&gt;@dogs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;HairlessFurever&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Please enter the number of the dog you would like more information on.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
        &lt;span class="vi"&gt;@dogs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&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="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HairlessFurever::Dog&lt;/span&gt;
    &lt;span class="nb"&gt;attr_reader&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;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:physical_characteristics&lt;/span&gt;

    &lt;span class="vc"&gt;@@all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
        &lt;span class="vi"&gt;@description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;
        &lt;span class="vi"&gt;@height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;
        &lt;span class="vi"&gt;@weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;
        &lt;span class="vi"&gt;@physical_characteristics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;
        &lt;span class="vc"&gt;@@all&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
        &lt;span class="c1"&gt;#HairlessFurever::DogCatcher.catch_dog_breeds if @@all.empty?&lt;/span&gt;
        &lt;span class="vc"&gt;@@all&lt;/span&gt; 
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;
        &lt;span class="n"&gt;dog&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;dog&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;physical_characteristics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All that is left is the rest of my CLI class. The &lt;code&gt;fetch_user_dog&lt;/code&gt; takes in the input of the user, turns in into an integer as we want this do find the &lt;code&gt;chosen_dog&lt;/code&gt; by the index assigned to it in the &lt;code&gt;fetched_dog&lt;/code&gt; method. This method than calls on the &lt;code&gt;show_dog(chosen_dog)&lt;/code&gt; method if the input is valid. The input is valid if it is greater than 1 and not more than the length of the array that all the dogs are housed in. It would have been easy here to just put if the input is between 1-10 then it is valid, but that isn't flexible. What if I wanted to expand this program? I would have to re-write this code. It isn't a huge deal at this point, but it is better to allow for the possibility of expansion. If the input isn't valid, then the program returns to &lt;code&gt;fetched_dogs&lt;/code&gt; and asks for input again. If the input is valid then it goes to the &lt;code&gt;show_dog(chosen_dog)&lt;/code&gt; method and puts the dog's name and description. It then asks if the user would like more information. If the input is "y" then it goes to the &lt;code&gt;details(chosen_dog)&lt;/code&gt; method where more information is put out to the user on the same dog and then it calls on the method of &lt;code&gt;continue&lt;/code&gt;. If the user enters anything other than "y" than the program also calls on the 'continue&lt;code&gt;method. In the&lt;/code&gt;continue&lt;code&gt;method the user is asked if they would like to see the list again, or if they want to exit. If they type "exit" then the program calls on the&lt;/code&gt;farewell&lt;code&gt;method. Remember that in the&lt;/code&gt;call&lt;code&gt;method, until the user input is "exit" continue to the loop the program. If the user enters anything other than "exit" than the program returns to&lt;/code&gt;fetched_dog&lt;code&gt;and the user is shown the list of dogs again. The&lt;/code&gt;farewell` method just puts out an ASCII dog and thanks the user. That is my program in a nutshell. It is very simple, but I am really proud of it. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`ruby&lt;br&gt;
class HairlessFurever::CLI&lt;br&gt;
 def fetch_user_dog&lt;br&gt;
        chosen_dog = gets.strip.to_i&lt;br&gt;
        #getting and checking user input to make sure it is valid &lt;br&gt;
        show_dog(chosen_dog) if valid_input(chosen_dog, @dogs) &lt;br&gt;
    end&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def valid_input(user_input, data)
    #input needs to be less than the amount of data(dog breeds) but more than 0 and can't be a negative number 
    user_input.to_i.between?(1, data.length)
    #user_input.to_i &amp;lt;= data.length &amp;amp;&amp;amp; user_input.to_i &amp;gt; 0 also works

end

def show_dog(chosen_dog)
    #show dog name and description 
    dog = @dogs[chosen_dog -1]
    puts "#{dog.name}: #{dog.description}"
    puts "\nWould you like to get more information on this dog? (y/n)\n"
    @input = gets.strip
    if @input == "y"
        details(chosen_dog)
    else
        continue
    end
end

def details(chosen_dog)
    #show more details about the selected dog breed
    dog = @dogs[chosen_dog -1]
    puts "#{dog.height}"
    puts "#{dog.weight}"
    puts "#{dog.physical_characteristics}"
    continue
end

def continue
    #see if user wants to continue or exit
    puts "\nPress any key to see the list of dogs again. Type 'exit' to leave.\n"
    @input = gets.strip
end

def farewell
    puts ""
    puts "             /)-_-(\\"       
    puts "              (o o)"          
    puts "      .-----__/\\o/"           
    puts "     /  __      / "             
    puts " \\__/\\ /  \\_\\ |/ "                
    puts "      \\\\     || "                 
    puts "      //     || "                 
    puts "      |\\     |\\ "                 
    puts "\nThanks for stopping by.\n"
    puts ""
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>oop</category>
    </item>
    <item>
      <title>Learning Ruby "Advanced" Class Methods</title>
      <dc:creator>Dorthy Thielsen</dc:creator>
      <pubDate>Fri, 21 May 2021 17:38:35 +0000</pubDate>
      <link>https://forem.com/dotnotation/learning-ruby-advanced-class-methods-pln</link>
      <guid>https://forem.com/dotnotation/learning-ruby-advanced-class-methods-pln</guid>
      <description>&lt;p&gt;For the last few days I have been learning about "advanced" class methods in Ruby. I am not sure if they are that advanced by a professional's standards but to me they are advanced in comparison. Basically I am learning about class constructors, self, finders, constants, class variables, etc. &lt;/p&gt;

&lt;p&gt;The lab I have been working on is to prep me for the big CLI music library final project in Ruby. The assignment is to create class methods to interact with class data regarding creating, finding, and storing song data including the artist name, song name, and the filename. I was given this block of code to begin with.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Song&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&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;:artist_name&lt;/span&gt;
  &lt;span class="vc"&gt;@@all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
    &lt;span class="vc"&gt;@@all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was already given my reader and writer methods for song name and artist name. I was also given my empty array that these items would be stored in and a method to save them into the array. &lt;/p&gt;

&lt;p&gt;My first task was to create three methods that would instantiate songs using a class method instead of the previously used instance method initialize so I could have more flexibility in my program. I was told to initialize the song, save the song and/or set the name property, and then return the song. For the whole lab, I was also told to try and call on my other class methods so my code wouldn't be repetitive and not abstract.&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="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;#initialize a song&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; &lt;span class="c1"&gt;#save the song using the save method&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="c1"&gt;#return the song&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;#initialize a song&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;#set the name to the name property&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="c1"&gt;#return the song&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="c1"&gt;#using the create method from above &lt;/span&gt;
     &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;#set the name to the name property&lt;/span&gt;
     &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="c1"&gt;#return the song&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also you can see that I have been doing more pseudocode so I am able to code more efficiently and know what steps I need to take. I have removed the rest of my pseudocode in the rest of my code so it is easier to read, but wanted to show that improvement.  &lt;/p&gt;

&lt;p&gt;Then it was time to build some finder methods. Including one that tripped up me and the technical coaches at Flatiron. For some reason since I had created a blank method later on in the code, it was causing my tests to fail and no one knows why. Anyways, I learned that instead of building complex methods that do multiple things, it is smarter to branch complex methods into smaller chunks. Then you can call on those methods to do larger things in another method, like the &lt;code&gt;self.find_or_create_by_name&lt;/code&gt; method below. Which in that method if the song is found in &lt;code&gt;self.find_by_name&lt;/code&gt; then return the name if not, &lt;code&gt;self.create&lt;/code&gt; the song. In the &lt;code&gt;self.find_by_name&lt;/code&gt; method, I wanted to use a finder method on self.all(the array method from above) to find a song and return the song. Then to sort the array alphabetically using the sort_by method. I first wrote the code &lt;code&gt;@@all.sort {|a, b| a &amp;lt;=&amp;gt; b}&lt;/code&gt; which also works but I was asked to use the sort_by method.&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="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&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="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_or_create_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
   &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alphabetical&lt;/span&gt;
    &lt;span class="vc"&gt;@@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&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;The next challenge was what to do with a filename string like "Taylor Swift - Blank Space.mp3". I wanted to separate the artist from the song name and get rid of the .mp3. First part was easy. I just need to use the split method and split it at the "-". Getting rid of the .mp3 was something foreign to me. I was looking at everything you can do with enumerables and came across the .gsub method. I highly recommended this &lt;a href="https://www.rubyguides.com/2019/07/ruby-gsub-method/"&gt;article&lt;/a&gt;. I used this method to get rid of the pesky .mp3 and substitute in an empty string. Then set the value of the artist name and returned the song.&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="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;artist_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;song_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&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="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;song_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".mp3"&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="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;artist_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;artist_name&lt;/span&gt; 
    &lt;span class="n"&gt;song&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_from_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt; 
    &lt;span class="n"&gt;song&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally to destroy everything!&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="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy_all&lt;/span&gt;
    &lt;span class="vc"&gt;@@all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt; &lt;span class="c1"&gt;#can also use @@all = []&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>ruby</category>
      <category>oop</category>
    </item>
  </channel>
</rss>
