<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: eliastooloee</title>
    <description>The latest articles on DEV Community by eliastooloee (@eliastooloee).</description>
    <link>https://dev.to/eliastooloee</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%2F289663%2F50a19f8f-a7e6-4170-b036-8e9d1aa9d9f7.png</url>
      <title>DEV Community: eliastooloee</title>
      <link>https://dev.to/eliastooloee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eliastooloee"/>
    <language>en</language>
    <item>
      <title>Coming tomorrow, learn why you should use your own router for better home wifi. </title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Sun, 23 Aug 2020 06:29:00 +0000</pubDate>
      <link>https://dev.to/eliastooloee/coming-tomorrow-learn-why-you-should-use-your-own-router-for-better-home-wifi-50n</link>
      <guid>https://dev.to/eliastooloee/coming-tomorrow-learn-why-you-should-use-your-own-router-for-better-home-wifi-50n</guid>
      <description>&lt;p&gt;I'm just too tired to write this post well tonight, but today I switched my Xfinity box to bridge mode and started using a Nighthawk router. I will write up a detailed explanation in the morning.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is a virtual DOM, and why do we utilize it so frequently when building modern single page applications? </title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Sun, 16 Aug 2020 06:53:54 +0000</pubDate>
      <link>https://dev.to/eliastooloee/what-is-a-virtual-dom-and-why-do-we-utilize-it-so-frequently-when-building-modern-single-page-applications-4501</link>
      <guid>https://dev.to/eliastooloee/what-is-a-virtual-dom-and-why-do-we-utilize-it-so-frequently-when-building-modern-single-page-applications-4501</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is a DOM?&lt;/strong&gt;&lt;br&gt;
Let’s start with the basics. A Document Object Mode, or DOM, is a programming interface through which HTML and XML can interact with programming languages like Javascript. It represents the document as a collection of nodes and objects, allowing object oriented languages to interact with it. It is what it says on the can. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a virtual DOM?&lt;/strong&gt;&lt;br&gt;
A virtual DOM (VDOM Henceforth) is also what it says on the can. It is an abstraction of the DOM, detached from a browser specific interface, where changes in state can be made without changes to the actual user interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is a VDOM helpful? How is it any different if it's just a representation of a DOM?&lt;/strong&gt;&lt;br&gt;
 A traditional HTML DOM is arranged as a tree, with tags acting as objects. Nested tags are children of the enclosing tags. Inner text is also an object and is a child of its tags. This arrangement means that after an update a tag and all of its children must be re-rendered, which is costly, particularly for large apps with enormous trees. &lt;br&gt;
    A VDOM works similarly to a DOM. When elements are changed in the UI a VDOM is created as a tree, with each element represented as a node. If the state of an element changes, a new VDOM tree is created. The VDOM trees are then compared, and the optimal method to make changes in the DOM calculated. At this point the DOM is re-rendered. &lt;br&gt;
    Pre-planning changes to the DOM avoids the expensive operations of needlessly re-rendering elements in the DOM tree. This is the primary advantage of the VDOM over the DOM. Think of it like going to the grocery store. You could just wander around, throwing things you need into your cart, but it would be slow. If you instead made a detailed list, pre-determined the locations of the list items in the grocery store, and calculated an optimal route ahead of time, you’d be done shopping much faster. That’s the VDOM. It’s the faster way of doing things.&lt;/p&gt;

</description>
      <category>react</category>
    </item>
    <item>
      <title>What is Firebase? Should you use it for your next project?</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Sun, 09 Aug 2020 06:07:33 +0000</pubDate>
      <link>https://dev.to/eliastooloee/what-is-firebase-should-you-use-it-for-your-next-project-443l</link>
      <guid>https://dev.to/eliastooloee/what-is-firebase-should-you-use-it-for-your-next-project-443l</guid>
      <description>&lt;p&gt;Should you use Firebase for your next project? It’s a question I’m quite familiar with, and one I hope to answer for others following in my footsteps. For those who are already familiar, go ahead and skip this post. For everyone who is still here, we’ll start with the basics.&lt;/p&gt;

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

&lt;p&gt;Firebase is a realtime document store. Let’s think about what that means in comparison to other options, like Postgres and MySQL, both of which are relational database management systems (RDBMS). An RDBMS uses a table-oriented model. The schema of a table is defined by the table name and a fixed number of attributes with fixed data types.  Operations are performed via database language commands, with SQL being the standard language. This should all sound pretty familiar to most readers.&lt;/p&gt;

&lt;p&gt;Document stores like Firebase differ from RDBMSs in that they are document oriented rather than table oriented. Document stores use a schema-free organization system, meaning records don’t require a uniform structure and can be nested. If that doesn’t mean anything to you, consider a real world analogy:&lt;/p&gt;

&lt;p&gt;Let’s say you have to keep track of cars on a dealer lot. The RDBMS model would be like having a spreadsheet, with defined columns for information about each car. You’d have columns for an ID (the primary key), vehicle name, category, model, fuel type, safety rating, and probably many other things. An equivalent document store model would be like having an individual document for each car on the lot, with the same information present on each document. &lt;br&gt;
If you wanted to add new attributes to the table-based RDBMS you’d have to update the schema with new columns and their data types. You’d be making a new spreadsheet. If you wanted to add new information to the document-based model you’d just add a new key-value pair to the document.&lt;br&gt;
The other defining characteristic of the relational (RDBMS) model is data normalization, where data is decomposed into smaller, related tables. Data is shared across multiple tables, resulting in less duplicates in the database, which is generally an advantage. Going back to our car lot analogy, we could separate cars and manufacturers into their own tables, thereby avoiding repeated information about manufacturers for each car produced by that manufacturer. This advantage of relational models is somewhat offset by the disadvantage of having to manage information changes across multiple tables. Spreading data across a rigid structure also makes changes more difficult once in production.&lt;br&gt;
In a document oriented database we could create separate structures for both manufacturers and cars. We could then make a reference to the manufacturer document in the car document, thereby creating a relationship between the objects. The primary advantage of this approach is ease of updating the schema, which requires only updating the documents for a given object and can be done without any system downtime. The other major advantage of document oriented systems is the ease with which information can be spread across multiple servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Okay, I know what Firebase (and document stores in general) are. So when should I use it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The short answer is that Firebase is a good choice for real-time applications, particularly applications that need scalability. Social media apps are a great example where something like Firebase is a good choice. Unfortunately, Firebase is part of Google Cloud. It is not open source, and you will have to pay. It can be a bad deal when you have a low number of users, but is actually a great deal if you have a large number of users, since it largely relieves you of having to hire back end developers to manage your infrastructure. If you anticipate many users, Firebase is a good choice. &lt;br&gt;
 RDBMS like Postgres are better suited to transactional, record keeping based applications. If you’re building an app to manage your client interactions, go ahead and use an RDBMS. Postgres, MySQL, and many other options are open source and can be used anywhere for free. &lt;br&gt;
    Lastly, if you’re just starting out as a developer, you should probably use an RDBMS and get familiar with how they work. It’s a core skill to have, and just because cloud platforms like Firebase are the future doesn’t mean the fundamentals are less important.  If your app won’t see production, Firebase is a waste.&lt;/p&gt;

</description>
      <category>database</category>
      <category>firebase</category>
      <category>rdbms</category>
    </item>
    <item>
      <title>Help! VS Code Source Control is listing every file on my computer! How can I just commit the changes from my current project? </title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Sun, 02 Aug 2020 06:40:57 +0000</pubDate>
      <link>https://dev.to/eliastooloee/help-vs-code-source-control-is-listing-every-file-on-my-computer-how-can-i-just-commit-the-changes-from-my-current-project-39m5</link>
      <guid>https://dev.to/eliastooloee/help-vs-code-source-control-is-listing-every-file-on-my-computer-how-can-i-just-commit-the-changes-from-my-current-project-39m5</guid>
      <description>&lt;p&gt;Like many developers, I have a bad habit of getting sucked into the code and forgetting to commit my changes to Github. One day a few months back I was happily coding along, adding new features to my React application. &lt;em&gt;Suddenly&lt;/em&gt; remembering that commits are important, I went ahead and clicked the source control tab, prepared to write the mother of all commit messages, and gritted my teeth for the inevitable merge conflicts.&lt;/p&gt;

&lt;p&gt;But it was much worse than that. For some reason, the source control tab listed every changed file in my development directory. The things I wanted to commit were there, but so were dozens of untracked algorithms and practice components from several different apps. This was a major problem, as I had no desire to store all these unrelated files in my new project repository.&lt;/p&gt;

&lt;p&gt;I started poking around the buttons on the source control tab, looking to see if I could remove all the unrelated files. It turns out I could remove them from the changes list by clicking the "discard changes" button, but doing so would totally delete them from my computer as well. Finding this solution less than optimal, I put on my thinking cap.&lt;/p&gt;

&lt;p&gt;Why was this happening? Why did everything show up on my changes list? Something must have been wrong with my file structure. I had done the usual when starting the project, creating a repository on Github and connecting it in the root directory of my project with the &lt;code&gt;git add remote origin&lt;/code&gt; command. Eventually, after much head scratching, I decided that there must be a git repository somewhere higher in the file structure that all my projects were connected to. I'd just have to find it. &lt;/p&gt;

&lt;p&gt;Fortunately, i was able to use the &lt;code&gt;git rev-parse --show-toplevel&lt;/code&gt; command. This command shows the top level directory of the working tree. In other words, it works backwards through the tree and returns the location of the first encountered git repository. Upon running this command, I received a result of &lt;code&gt;/Users/[my name]/Development/code&lt;/code&gt;. If you couldn't guess from the name, this is where my coding projects live. And there was a git repository there, inconveniently connecting them all together. I had found the source of my problem.&lt;/p&gt;

&lt;p&gt;Now for a solution or two. The most obvious solution would be to remove the .git file from my &lt;code&gt;code&lt;/code&gt; directory. I opened a terminal window to this directory and entered the &lt;code&gt;git log&lt;/code&gt; command to see if I could delete it without losing any valuable history. Unfortunately, there was quite a bit of history present, and I didn't want to deal with it at the moment. I just wanted to commit my project changes. If you are in this situation and the &lt;code&gt;git log&lt;/code&gt; command returns nothing or nothing meaningful, go ahead and delete the git file from the directory, and you should be good to go. If &lt;code&gt;git log&lt;/code&gt; returns history and you don't want to deal with it, read on.&lt;/p&gt;

&lt;p&gt;Fortunately for me, there is another solution. Git starts at the bottom of the tree and works its way up, meaning it will stop at the lowest repository it finds. I cd'd back into the root directory of my project and entered the &lt;code&gt;git init&lt;/code&gt; command to initialize a new repository. I followed this up with the &lt;code&gt;git remote -v&lt;/code&gt; command to see where my project was now connected, and received no response (meaning no remote existed). This was expected, as I had initialized an empty repository and never connected to it. I then ran the &lt;code&gt;git remote add origin [my repository]&lt;/code&gt; command to connect my project to the repository. The process was successful; when I returned to the source control tab in VS Code I saw only files that were part of my project. I breathed a sigh of relief and got back to work.&lt;/p&gt;

&lt;p&gt;Here's the TL;DR for those who find themselves in this situation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the &lt;code&gt;git rev-parse --show-toplevel&lt;/code&gt; command from the root directory of your project. This will tell you where to go.&lt;/li&gt;
&lt;li&gt;Navigate to the directory found in Step 1, then enter the &lt;code&gt;git log&lt;/code&gt; command to see if there is any history you need to keep. If there isn't, delete the .git folder in this directory and your problem should be solved.&lt;/li&gt;
&lt;li&gt;If there is history you need to keep, navigate back to the root directory of your project and enter the &lt;code&gt;git init&lt;/code&gt; command. Then run the &lt;code&gt;git remote -v&lt;/code&gt; command to make sure you aren't connected to any remote. Once you know you aren't connected, use the &lt;code&gt;git remote add origin [your github repository url]&lt;/code&gt; command. You should be good to go.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>github</category>
      <category>vscode</category>
      <category>react</category>
      <category>git</category>
    </item>
    <item>
      <title>Post Requests in Javascript</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Mon, 02 Mar 2020 17:45:19 +0000</pubDate>
      <link>https://dev.to/eliastooloee/post-requests-in-javascript-8d8</link>
      <guid>https://dev.to/eliastooloee/post-requests-in-javascript-8d8</guid>
      <description>&lt;p&gt;During the most recent code challenge at Flatiron School's Seattle Campus, it became clear that many students lack a clear understanding of the format for POST and PATCH requests. Let's walk through a simple post request to find out exactly how it works, line by line and step by step. We'll be using an example from one of our in class pair programming exercises. This POST request is to create a new Pokemon in our database.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function addPokemon(trainer) {&lt;br&gt;
    fetch(`http://localhost:3000/pokemons/`, {&lt;br&gt;
        method: "POST",&lt;br&gt;
        headers: { "Content-Type": "application/json",&lt;br&gt;
                    Accept: "application/json"&lt;br&gt;
                },&lt;br&gt;
        body: JSON.stringify({trainer_id: trainer.id})&lt;br&gt;
    })&lt;br&gt;
    .then(res =&amp;gt; res.json())&lt;br&gt;
    .then(data =&amp;gt; {&lt;br&gt;
      listPokemon(data)&lt;br&gt;
    })&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;First we see a 'trainer' being passed into the function. This is because we want to associate the Pokemon we are creating with the trainer who has captured it. &lt;/p&gt;

&lt;p&gt;Next we see a fetch request. This specifies where our POST request will go. We need the result of this fetch before we can proceed with the rest of our request. &lt;/p&gt;

&lt;p&gt;Next we see the method "POST". This specifies the type of request we are making. &lt;/p&gt;

&lt;p&gt;We then come to headers. The headers job is to tell the server what type of data to accept and what to send back. In this case we're telling the server that we will be sending JSON (Javascript Object Notation) and expect to receive JSON back.&lt;/p&gt;

&lt;p&gt;The next piece is the line that says "JSON.stringify". This line converts the object we are sending into a JSON string.&lt;/p&gt;

&lt;p&gt;Our Post request ends at at this point. In the following lines we are handling the data we get back. We first pass it to the .json function, will receive it as a promise with JSON content. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>What is P = NP and Why Does it Matter?</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Wed, 05 Feb 2020 00:12:15 +0000</pubDate>
      <link>https://dev.to/eliastooloee/what-is-p-np-and-why-does-it-matter-4jlm</link>
      <guid>https://dev.to/eliastooloee/what-is-p-np-and-why-does-it-matter-4jlm</guid>
      <description>&lt;p&gt;Does P = NP? No one really knows at this point, and you can get a million dollars if you figure it out. The first step to earning a million dollars is thus determining what the question means. In a nutshell, it asks whether any problem with a solution that can be verified quickly can also be solved quickly. &lt;/p&gt;

&lt;p&gt;There’s a lot in there, so we need to break it down. First, what does quickly mean? In this context, quickly means that the algorithm runs in polynomial time. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But what does polynomial time mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Polynomial time refers to the time complexity of the algorithm, or how long it takes to find a solution. Time complexity  is generally expressed using Big O notation. Polynomial time specifically means that the running time for the algorithm is upper bounded by a polynomial the size of the algorithm input:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(n^c)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An algorithm of exponential time complexity has a runtime of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(c^n)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It is immediately obvious that an algorithm of exponential time complexity will grow much faster than an algorithm of polynomial time complexity, regardless of the value of the constant C. This is why an algorithm must be of polynomial time complexity to be considered quick. &lt;/p&gt;

&lt;p&gt;Problems that can be solved by an algorithm in polynomial time are Class P problems. Problems that cannot be solved in polynomial time, but with an answer that can be verified in polynomial time, are Class NP problems. &lt;/p&gt;

&lt;p&gt;An example of a class P problem is string matching:&lt;br&gt;
&lt;em&gt;Given two strings, P and T, determine whether P occurs as a contiguous substring of T.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If P= “rocket” and T= “The rocketry expert is here” the answer is yes. The algorithm can simply check each position in T to see if P occurs at that position.  If we suppose that P has length U and T  has length V, there are V-U+1 positions to check, and it takes no more than U steps to check each position. This makes the total time to solve the problem proportional to U(V-U+1). We can see that the time taken is highest when V is about 2U, which means u = (n/3), and the time is (n/3)(n/3), which is O(n^2) in Big O notation.&lt;/p&gt;

&lt;p&gt;An example of a class NP problem is Integer Factorization: &lt;br&gt;
&lt;em&gt;Given integers n and m, is there and integer f with 1 &amp;lt; f &amp;lt; m such f divides n?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If someone gives us an answer to this problem (n, m, and 1 &amp;lt; f &amp;lt; m, with the claim that f  is a factor of n), we can easily check the result in polynomial time by performing the division n/f. While algorithms to solve this problem do exist, they all run in exponential time. &lt;/p&gt;

&lt;p&gt;Given this background, we can understand what the question P = NP? Is asking. It is asking whether, since a solution to problems like Integer Factorization can be verified so quickly, it is possible to find a solution in a comparable amount of time?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is this important?&lt;/strong&gt;&lt;br&gt;
    If it turns out that P = NP is true, then there is a faster solution for all class NP problems, and we just haven’t found it yet. If !P = NP, then at least some subset of NP problems are not possible to solve in polynomial time. This essentially tells us which problems are easy for computers to solve, and which are not (note that a problem being class P does not necessarily mean that it is efficient for current computers to solve, only that a theoretical computer is capable of efficiently solving it). It is currently assumed that P != NP, so ultimately a proof showing this to be the case would only confirm what most already believe to be true. This conclusion would change little, although it would affirm most current cryptography techniques, which depend on our inability to efficiently factor large numbers. It would also show that the current approach to NP problems, which is to find workarounds to convert them to P problems, is our best path forward. The exciting, if unlikely, possibility is that P = NP. Public-key cryptography would become impossible. Everything would be ultra optimized, from transportation to computation. Artificial intelligence would make massive leaps. This conclusion would radically alter our whole world. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Fetch in JavaScript</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Tue, 04 Feb 2020 16:45:14 +0000</pubDate>
      <link>https://dev.to/eliastooloee/using-fetch-in-javascript-3i7c</link>
      <guid>https://dev.to/eliastooloee/using-fetch-in-javascript-3i7c</guid>
      <description>&lt;p&gt;Sometimes we need to get information from an API. Since the 2015 updates to JavaScript, fetch() is the best way to go about this. Below I will explain the ES6 syntax for using fetch().&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function getBooks() {&lt;br&gt;
    fetch('http://localhost:3000/books')&lt;br&gt;
    .then((response) =&amp;gt; {&lt;br&gt;
        return response.json();&lt;br&gt;
    })&lt;br&gt;
    .then((books) =&amp;gt; {&lt;br&gt;
        renderBooks(books);&lt;br&gt;
    });&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Here we can see a function getBooks, which will communicate with an API. The first step is use fetch, followed by the Url of the API inside the parentheses. This gets us the promise from the API, but the information is not usable. We then pass the response from fetch() into the next function to get the JSON data from the promise, and finally we name the JSON data 'books' and pass it to the function renderBooks.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function renderBooks(books) {&lt;br&gt;
    books.forEach(book =&amp;gt; {&lt;br&gt;
        renderBook(book)&lt;br&gt;
    });&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Render books simply calls another function, renderBook, that will display each book. We pass book into this function. We then look at the HTML and find the element "list". We then target "list and create a new element called li. We set the content of this new element to be book.title, then append it to the list. We also add an event listener to li that will call the function showBookCard when li is clicked. We must pass in an empty function for this to work. If we do not pass an empty function, the event listener will run on page load, which we do not want.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function renderBook(book) {&lt;br&gt;
    const unorderedList = document.getElementById("list");&lt;br&gt;
    const li = document.createElement("li");&lt;br&gt;
    li.textContent = book.title&lt;br&gt;
li.addEventListener("click", () =&amp;gt; showBookCard(book))&lt;br&gt;
    unorderedList.appendChild(li)&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Next, we have function showBookCard, which will create a display that is triggered by the event listener attached to li.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```function showBookCard(book) {&lt;br&gt;
    const showPanel = document.getElementById("show-panel")&lt;br&gt;
    showPanel.innerHTML = "";&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const coverImage = document.createElement("img")
coverImage.src = book.img_url

const description = document.createElement("h1")
description.textContent = book.description

const button = document.createElement("button")
button.textContent = "Like"
button.addEventListener("click", () =&amp;gt; likeBook(book))

const usersList = document.createElement("ul")

book.users.forEach(user =&amp;gt; {
    const userLi = document.createElement("li");
    userLi.textContent = user.username;
    usersList.appendChild(userLi);
})

showPanel.appendChild(coverImage)
showPanel.appendChild(description)
showPanel.appendChild(button)
showPanel.appendChild(usersList)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;}```&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This function looks enormous, but is actually quite simple. We first look at the HTML to find the element "show-panel" and set it to a constant showPanel. We set its innerHTML equal to an empty string to make sure any content disappears when a user clicks away. We then create a constant called coverImage and set its source to book.img_url. We then append coverImage to showPanel. We can follow the same steps for the book description, substituting textContent for source. We then create a button called "Like" that will allow a user to like a book and attach an event listener to it that will call the function likeBook when the button is clicked. We then create an element called usersList with a "ul" tag. We then use forEach to iterate through the books users (user must be passed in), creating an "li"for each one and setting the textContent equal to their username. We then append the user to to the list. All of these elements must then be appended to showPanel.&lt;/p&gt;

&lt;p&gt;We then come to the function likeBook, which is called when a user clicks the like button on a book card.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function likeBook(book) {&lt;br&gt;
    book.users.push(userName)&lt;br&gt;
    fetch(`http://localhost:3000/books/${book.id}`, {&lt;br&gt;
        method: "PATCH",&lt;br&gt;
        headers: {&lt;br&gt;
            "Content-Type": "application/json",&lt;br&gt;
            Accept: "application/json"&lt;br&gt;
        },&lt;br&gt;
        body: JSON.stringify({users: book.users})&lt;br&gt;
    })&lt;br&gt;
    .then(res =&amp;gt; res.json())&lt;br&gt;
    .then(likedBook =&amp;gt; showBookCard(likedBook));&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This function accepts book as an argument. It then pushes the current user into the book's array of users. It then uses fetch to send a patch request to our API. A PATCH request updates only some of an object, rather than replacing everything like a PUSH request,. We use headers and a body tag to tell the API what kind of data it will be receiving and sending. We then convert the response to JSON and pass it to likedBook and showBookCard, which will update the DOM to reflect changes to the API.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>All Your Packets Are Belong To Us</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Tue, 28 Jan 2020 00:03:59 +0000</pubDate>
      <link>https://dev.to/eliastooloee/all-your-packets-are-belong-to-us-5d6f</link>
      <guid>https://dev.to/eliastooloee/all-your-packets-are-belong-to-us-5d6f</guid>
      <description>&lt;p&gt;While we’re often told that privacy no longer exists and that everything we do online is recorded for eternity, few of us really take it to heart or realize just how vulnerable we are to individual hackers, snoopers, and fraudsters. To demonstrate this vulnerability, I will show just how much personal information an individual with access to a laptop can collect over a shared Wifi network. Remember, I have no idea what I’m doing, I’m just a guy who googled and found some free tools. An expert could almost certainly do much more. &lt;/p&gt;

&lt;p&gt;First, let’s look at what we can do using only applications included on a newish MacBook Pro. If we go to Finder &amp;gt; Locations &amp;gt; Network we can see all the other computers connected to the network we’re currently using. Depending on the owner’s share settings we may be able to view their screen or  access their files. You can protect yourself against this vulnerability (on a Mac) by going to System Preferences &amp;gt; Sharing and making sure everything is turned off. Unfortunately, many users ignore these settings or are unaware of them. Remember, this is in a building full of software developers, who should theoretically be much more aware of this sort of thing than the average computer owner, yet we still see more than a dozen computers allowing either screen or file sharing. We won’t access any of these computers since it would be a massive violation of workplace privacy (and also potentially illegal), but if we wanted to it would be as easy as clicking on them. &lt;/p&gt;

&lt;p&gt;Moving on from the basics, if we open Network Diagnostics and go the Window tab in the menu bar we can select Sniffer, which will allow us to collect WiFi traffic over the network we are connected to. This traffic will be stored in a folder called var/temp. This folder is generally hidden from view, but can be accessed by opening your terminal and entering the command open $TMPDIR. Our computer doesn’t contain a good application for viewing these files, so we’ll need to download one. Wireshark is free and is considered the standard choice, so we’ll go with that. After downloading Wireshark we can open the .pcap file generated by our sniffer and examine the data within. As an easier option, Wireshark includes sniffer functionality, so we can just use that. To do so we select the network interface we want to sniff, then click start live capture. We will then see a stream of packets. As an example we will now go to a website in our browser and login (choose an unsecured website). After successfully logging in, we can go back to Wireshark and click stop live capture. We can then use the filter on Wireshark to look at only http requests collected while we were sniffing. We’ll look under the ‘info’ column for any POST requests. We can then click on the POST request (there should only be one since we had such a short capture) and look at its data. We can then scroll down until we see a section called HTML Form URL Encoded. Looking inside this section we can see both the email and password used to login. We may have performed this example exclusively on our own computer, but it will work for any computer on a shared network, as long as the site is not secured (HTTPS). There is a way to do the same thing for secured sites, but it is very illegal and could be quite useful to those with bad intentions, so we won’t cover it here. &lt;br&gt;
    That’s it for today, but check back later this week for more posts on this topic in greater detail. This post will also be updated with images this afternoon. Hopefully you’ve now seen how risky shared networks can be. Maybe just use your data instead of connecting at Starbucks.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why Am I Here?</title>
      <dc:creator>eliastooloee</dc:creator>
      <pubDate>Mon, 13 Jan 2020 19:43:00 +0000</pubDate>
      <link>https://dev.to/eliastooloee/why-am-i-here-2f19</link>
      <guid>https://dev.to/eliastooloee/why-am-i-here-2f19</guid>
      <description>&lt;p&gt;Why am I here? Why drop everything I studied in college? Why become a software developer? These are all important questions, and the answers require looking back in time. I began my post-high school academic life as a kinesiology major, as is common for athletes who aren’t good enough to keep playing the games they love in college. That didn’t last long. I transferred to a new college, only to find that their kinesiology program had a two year backlog. I needed a new major, so I just picked one at random. My only requirements were that it was STEM, and that I could graduate sooner than was possible in kinesiology. I landed on geophysics, a subject about which I knew nothing, and started on the prerequisites. This was my first exposure to programming, as I was required to take Intro to Programming in C++ my first quarter. The instructor was below average, and the classmates antisocial, but I was hooked. It easily beat out calculus, physics, and geology as my favorite class that quarter. I looked into majoring in computer science, but found that it also had a multi-year backlog. The quarter ended, and it was time to leave coding behind, but the mindset I learned that first quarter stuck with me. Throughout the rest of my university education I gravitated towards the technological aspects of earth science, focusing on  arcGIS, MATLAB, and lidar while my classmates hammered rocks and looked at the fragments under a microscope. Then school was over, and it was time to get a job. The oil industry, the primary employer for recent earth science grads, was down, so  I found work doing seismic refraction surveys in the mountain west. This was basically seasonal work, with little to do in the winter, and was less than fulfilling. After a year and a half my contract wasn’t renewed, and it was time to look for something new. That was when, like something out of a bad movie, I heard an ad for Flatiron School on the radio while I was home visiting my dad. I did a little research and sent in an application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ym5fwakd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ps3fu51x1s9o36cq7py0.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ym5fwakd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ps3fu51x1s9o36cq7py0.JPG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
 Me during Summer 2018, looking like the opposite of a future software developer. 



&lt;p&gt;Now I’m here, and for the first time in my life I know why. I’m here because I like to make things, and I like to do it my own way. I have the spirit of a crackpot garage inventor. Unfortunately, the age of lone inventors is long gone, the low-hanging invention fruit of the physical world  having been thoroughly picked over. Programming is different. That’s what I was drawn to during my initial exposure. Everything is still in its infancy, with little set in stone. There is still room for individual innovation and contribution. I was born too late for the industrial revolution, but just in time for the digital revolution, and I fully intend to participate. &lt;/p&gt;

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