<?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: jessrichmond</title>
    <description>The latest articles on DEV Community by jessrichmond (@jessrichmond).</description>
    <link>https://dev.to/jessrichmond</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%2F457378%2F1121ceb5-57cd-4c27-add3-80885b73fd2e.png</url>
      <title>DEV Community: jessrichmond</title>
      <link>https://dev.to/jessrichmond</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jessrichmond"/>
    <language>en</language>
    <item>
      <title>💾  ✨ Eager loading: in database queries and also in skill growth </title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Tue, 17 Nov 2020 18:26:57 +0000</pubDate>
      <link>https://dev.to/jessrichmond/eager-loading-in-database-queries-and-also-in-skill-growth-1dk6</link>
      <guid>https://dev.to/jessrichmond/eager-loading-in-database-queries-and-also-in-skill-growth-1dk6</guid>
      <description>&lt;p&gt;Well folks, my coding bootcamp experience is almost over. I’ve spent the past seven months hustling to learn full-stack Javascript, and it has culminated in a three week long thesis project in which I worked on a team to develop Goldilocks, a web application for users to facilitate one-to-one room swaps (think Airbnb sans exploitation and/or very short term, reciprocal subletting).&lt;/p&gt;

&lt;p&gt;Goldilocks is a full stack application; we used React.js on the front end, Node.js and Express server-side, and Postgres with Sequelize for our database handling. While our database was nowhere near being classified as complex, it was the most nuanced approach anyone on my team had ever been faced with, and while a bit overwhelming at first glance, it was my favorite aspect of the project especially because I developed what I think are some really solid habits that lend themselves to best practice.&lt;/p&gt;

&lt;p&gt;My database handling practice has come such a long way in the past couple of months (and it still has, undoubtedly, a lot of room for growth!). It’s sweet to reflect on how it has evolved &amp;amp; how my skills have, in time, loaded:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In my first semi-autonomous project, I was setting up components on the front end that made HTTP requests via Axios to the database, which then sent the response &lt;em&gt;back&lt;/em&gt; to the front end, where I waited for that response to make &lt;em&gt;another&lt;/em&gt; request to the database... &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This approach was getting me the responses I was looking for, but I had a feeling that this wasn’t right. On my second project, a teammate helped me realize that that should all be done on the backend. I consolidated my requests a bit in that only one HTTP request was being made to the database from the frontend, but the code on the backend was a mess! I was chaining queries to other queries, and oh boy, there were many lines of code to be had. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This also did not feel right! It was easy to get lost in the code and be unsure of what response was coming back from where, so when it was time to get started on Goldilocks, I did some research into more efficient database querying. My crown jewel was discovering “eager loading” and learning that all of the database queries associated with one specific request from the frontend could be bundled into a singular response.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took me a couple of tries to get it right. For it to work as intended, all model associations need to be set up properly, so my team and I had to go back and update our foreign keys (Postgres uses camelCase by default and not snake_case like we thought!) and then ensure all of our hasOne / hasMany / belongsTo / belongsToMany statements accurately demonstrated the relationships we were setting up. It was a hurdle having to go back and do that, but I knew that taking time to go back and adjust our models would pay off once we could integrate eager loading into our database query workflow. Once we got everything reconfigured, I could not stop singing the praises of eager loading! And what is even funnier is that four months ago, I was convinced that backend was not for me! I'm now finding myself getting fixated on learning more about query performance and being confident in my choices of data handling, and now that Goldilocks development is being put on hiatus &amp;amp; my program is wrapping up, I'm excited to transfer what I've learned thus far into a career.&lt;/p&gt;

&lt;p&gt;Thanks for reading for the past couple of months y'all. Ttyl.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exploring Mastodon &amp; Thinking about the Decentralized Web 🌀 🌈</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Tue, 10 Nov 2020 07:02:24 +0000</pubDate>
      <link>https://dev.to/jessrichmond/exploring-mastodon-thinking-about-the-decentralized-web-g1n</link>
      <guid>https://dev.to/jessrichmond/exploring-mastodon-thinking-about-the-decentralized-web-g1n</guid>
      <description>&lt;p&gt;Would I be the person I am today had I not spent hours and hours on the Internet as a young teen in the mid to late 2000s scrolling through sites like Myspace and Tumblr? I honestly do not think so! Having the opportunity to effortlessly interact with people my age from all over the world was wild! That time online genuinely broadened my imagination &amp;amp; I will always think fondly of my online experiences during those formative years. However, it feels like this experience is out of reach these days - and I don't think it's only because I'm older. Social media networks have grown exponentially and with sites like Facebook, Instagram, and Twitter, it’s become a far lot less about connecting with others than it has become about raking in revenue. While my desire to use these platforms has diminished, my desire to connect with my friends and other people I share interests with has not. I would just rather my data not be owned by corporations who are trying exploit that data in order to meet financial benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Cue Mastodon. Cue decentralized networking apps. Cue the Fediverse!&lt;/em&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h5&gt;
  
  
  (We are not talking about the metal band Mastodon here)&lt;a href="https://www.youtube.com/watch?v=hIw7oeZKpZc"&gt;.&lt;/a&gt;
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://docs.joinmastodon.org/"&gt;Mastodon&lt;/a&gt; is an open source microblogging project that wants to put social networking into the hands of its users. Similar to apps like Twitter and Tumblr, users share short messages called toots &amp;amp; follow other users to read (and boost) their toots. Dissimilar to apps like Twitter and Tumblr (and really any other huge corporate social media platform), Mastodon is not a central hub - rather, it is a network of connected servers, referred to as instances.&lt;/p&gt;

&lt;p&gt;It is during the signup process for Mastodon that you select (or apply to) the server you want to be a member of; each server transparently lays out its purpose + values + guidelines, making it easy for new users to find their place.&lt;/p&gt;

&lt;p&gt;Once you are a member of a server, you’ll be able to pick and choose the other folks on your server you’re interested in following. You’ll be able to see their toots, of course, but because each Mastodon server can communicate with other Mastodon servers, as mentioned before, you can be signed up one server and still easily interact with users on other servers.&lt;/p&gt;

&lt;p&gt;This configuration fits into the federated model of decentralization (hence, Mastodon’s belonging in the Fediverse), and this model can be best explained by a comparison to email. Because all email servers use the same protocol to communicate, it ultimately does not matter which email provider you use. I can have a Gmail account and send a message to someone with an AOL account (my mom, probably) and it will go off without a hitch because those providers speak the same language.&lt;/p&gt;

&lt;p&gt;A very similar thing is happening in the Fediverse. Mastodon, and other federated platforms, communicate using ActivityPub which defines how servers handle new user posts &amp;amp; how they can be interacted with. Any platform or application that implements ActivityPub is accessible to you on your Mastodon server. Imagine being able to log into one place and have your Facebook, Instagram, Youtube, and Twitter feed all in one place. That’d never happen because of corporate greed, but with the Fediverse you can do that. ActivityPub allows users to configure their experience on Mastodon (or any federated app) to not only interact with users on other Mastodon servers but also to include content from video platforms like Peertube and Funkwhale, image hosting platforms like Pixelfed, and blogging platforms like Plume or Write.as.&lt;/p&gt;

&lt;p&gt;So what happens if you nose around on Mastodon and don’t find a server that suits your particular needs and desires? Well friend, head on over to the Mastodon code on Github and fork that baby down. Set up a new Mastodon instance to your preference &amp;amp; then define the vision and rules of that instance. Invite your friends, invite your family, invite your neighbors! Update your fork with personalized custom features. You are the leader - even if only temporarily - here; build/help build a meaningful community.&lt;/p&gt;

&lt;p&gt;It is worth noting that setting up your own Mastodon instance is not a zero cost project. If you limit the size of your server, it is not an insanely expensive endeavor but do keep in mind that running a Mastodon (or any other ActivityPub app) instance comes with the cost of running and maintaining servers. Purposefully not generating ad revenue is pretty crucial to the premise of decentralized social networks; the operating cost of a Mastodon server is usually crowd funded by its users.&lt;/p&gt;

&lt;p&gt;While Mastodon and other apps in the Fediverse are likely to never replace to the huge social media giants, I think I’m ok with that! Whereas Facebook has over a billion users, Mastodon only has about 2 million users spread out over 6500 instances worldwide; clearly this indicates that there’s an interest for something else and more community driven and &amp;amp; you can count me in that number. I’m looking forward to exploring Mastodon once I find myself with some more free time (coming soon!) and I’d encourage you to do the same.&lt;/p&gt;

&lt;p&gt;I’d also like to shout out to Darius Kazemi and his moral + approachably technical guide to setting up your own social network on Mastodon, which is where I was introduced to this subject. You can (you should!) read that &lt;a href="https://runyourown.social/"&gt;here.&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Ps, header image was in part sourced via &lt;a href="https://botsin.space/@wildflowersbot"&gt;wildflowersbot@botsin.space&lt;/a&gt;, a bot on Mastodon that generates digital vistas of wildflowers. Way cool.
&lt;/h6&gt;

</description>
      <category>fediverse</category>
    </item>
    <item>
      <title>Reflections on Accessibility as a Budding Software Engineer </title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Wed, 28 Oct 2020 15:49:52 +0000</pubDate>
      <link>https://dev.to/jessrichmond/reflections-on-accessibility-as-a-budding-software-engineer-1cip</link>
      <guid>https://dev.to/jessrichmond/reflections-on-accessibility-as-a-budding-software-engineer-1cip</guid>
      <description>&lt;p&gt;The end of my coding bootcamp is approaching and it really feels like we - my cohort mates and I - are scaling up: in skill development, in project scope, in preparing for career transitions. While we’ve still got a bit of work ahead of us before we finish our program, it does feel like we are in the clear from most of the Immersion madness. Now that we are regaining our free time &amp;amp; our mental energy and are able to be a bit more thoughtful and reflective on the software dev work we are doing and want to do, we must get in the habit of thinking about how other people - especially people who have wonderfully different perspectives - will interact with &amp;amp; be affected by our web apps. We’ve got to get in the habit of developing with inclusivity and accessibility in mind.&lt;/p&gt;

&lt;p&gt;When people hear about making the web accessible for disabled people, maybe the most immediate thought is “ok, how can I make my site accessible to someone who is blind and cannot see it?” However, the spectrum of functional disability is vast. There are 61 million people in the United States living with a disability and those disabilities range from mobility to cognition to independent living and self care; sometimes these disabilities are temporary, sometimes they are lifelong. When developing our apps, we must shift our perspective to consider what issues disabled people might face when using these apps and we must strive to eliminate those barriers… if we don’t, we are effectively excluding 25% of the US population.&lt;/p&gt;

&lt;p&gt;This has been recognized by the World Wide Web Consortium (W3C) since the mid 1990s. They are the main international standards organization for the Internet, and in 1999, W3C released the first edition of the Web Content Accessibility Guides (WCAG); in 2008, they expanded on those guidelines and released WCAG 2.0. &lt;/p&gt;

&lt;p&gt;WCAG mandates that websites be POUR: that is, perceivable, operable, understandable, and robust to its users. Let’s touch briefly on these four principles.&lt;/p&gt;

&lt;p&gt;To be &lt;strong&gt;&lt;em&gt;perceivable&lt;/em&gt;&lt;/strong&gt;, a website should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide text alternatives for any non-text content&lt;/li&gt;
&lt;li&gt;Provide alternatives for time based media like video and audio&lt;/li&gt;
&lt;li&gt;Create content that can be presented in different ways without losing its integrity ie its meaning or structure&lt;/li&gt;
&lt;li&gt;Make it easier for users to see and hear content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be &lt;strong&gt;&lt;em&gt;operable&lt;/em&gt;&lt;/strong&gt;, a website should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be fully operable via keyboard&lt;/li&gt;
&lt;li&gt;Give users ample time to read and use content&lt;/li&gt;
&lt;li&gt;Not be designed in a way that is known to trigger seizures&lt;/li&gt;
&lt;li&gt;Help users navigate, find content, and determine where they are&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be &lt;strong&gt;&lt;em&gt;understandable&lt;/em&gt;&lt;/strong&gt;, a website should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make text easy to physically read and mentally comprehend&lt;/li&gt;
&lt;li&gt;Be predictable and both appearance and functionality&lt;/li&gt;
&lt;li&gt;Help users avoid mistakes and correct them if they occur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be &lt;strong&gt;&lt;em&gt;robust&lt;/em&gt;&lt;/strong&gt;, a website should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be as compatible as possible with various user agents, such as assistive technologies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are three levels for complying with WCAG guidelines: A, AA, and AAA. If a website is &lt;strong&gt;&lt;em&gt;Level A&lt;/em&gt;&lt;/strong&gt;, congrats. They have done the absolute bare minimum in following federal guidelines and are providing the most basic web accessibility features. What everyone in the the professional software dev world should instead be striving for is at least &lt;strong&gt;&lt;em&gt;Level AA&lt;/em&gt;&lt;/strong&gt;, which addresses the most common barriers for disabled web users. &lt;strong&gt;&lt;em&gt;Level AAA&lt;/em&gt;&lt;/strong&gt; can be achieved by providing the most complex and comprehensive level of web accessibility. Being AAA compliant is no easy feat, but there are a couple of features that are easy to implement in an already AA compliant environment - &lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/"&gt;here's a link to WCAG's overview where you can familiarize yourself with accessible features.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get in the habit of thinking about these things. Take one for the team. Show some empathy. What we are designing and developing as software engineers has the potential to impact people’s lives in meaningful ways. Let’s leave this world better than we found it.&lt;/p&gt;

</description>
      <category>a11y</category>
    </item>
    <item>
      <title>Testing APIs &amp; Getting the Most Out of Your Postman Workflow</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Mon, 19 Oct 2020 04:44:05 +0000</pubDate>
      <link>https://dev.to/jessrichmond/testing-apis-getting-the-most-out-of-your-postman-workflow-6m8</link>
      <guid>https://dev.to/jessrichmond/testing-apis-getting-the-most-out-of-your-postman-workflow-6m8</guid>
      <description>&lt;h3&gt;
  
  
  🔍 &lt;strong&gt;On being exposed to API requests for the first time&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When setting up an app that will rely on third party APIs, it is important to make sure that whatever API you’re interested in will give you the data that you are after. You could go straight to your code and make requests to the API from your server and log to the console until you pinpoint the query you need to make to receive the response you want, but this would involve restarting your server and/or refreshing your webpage at least once but most likely way more than only once. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---4oGj7sh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/xT5LMSd3cMXG1n3BSw/200_d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---4oGj7sh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/xT5LMSd3cMXG1n3BSw/200_d.gif" alt="gif of a person refreshing a webpage over and over"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how my introduction to API calls went. I wasted a whole lot of time refreshing and revising before being satisfied with the response I’d receive from the API, and for a while, I accepted this fate. An instructor had introduced us to Postman without providing much context, so it took a while before I began to grasp what a helpful tool API clients (!!! Postman) can be for project setup. Now that I'm officially a fan of Postman, I encourage you to learn the ins and outs as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ &lt;strong&gt;Streamlining the process with Postman&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So! Open up your desktop Postman app and follow along. Let's work to make this process as seamless as we can make it. When starting a new project, you'll want to set up a new workspace for you and your team members. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dteHxJ3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/qYqs1Y5/Screen-Shot-2020-10-18-at-9-28-45-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dteHxJ3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/qYqs1Y5/Screen-Shot-2020-10-18-at-9-28-45-PM.png" alt="create workspace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a workspace, name it whatever your heart desires, and invite your teammates via email. Once you have confirmed you are in that workspace, create a collection (this will be accessible by everyone on your team) and populate it with API requests. I've seen folks organize group their requests in collections according a specific method of required authentication, but as someone currently working on small projects that require only a handful of calls, I create my collections to reflect my projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oHoklCBA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/j41cL81/collections-in-workspace.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oHoklCBA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/j41cL81/collections-in-workspace.png" alt="postman collections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are two projects I've recently worked on. &lt;em&gt;On the Road&lt;/em&gt; is an app that maps out public campsites for people on road trips based on the number of hours they are willing to drive everyday until they reach their destination. Information for these campsites is retrieved using APIs from Recreation.gov and Reserve America. &lt;em&gt;Radma&lt;/em&gt; was built as a resource to connect with one's local music scene. When my team inherited this legacy code, I added a tool to discover music based on genres a fan is interested in; this was done using Spotify's API.&lt;/p&gt;

&lt;h3&gt;
  
  
  🗝 &lt;strong&gt;API requests, authentication methods, &amp;amp; shortcuts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before I plugged any of these APIs into my code, I used Postman to run tests to help me figure out how to access their data. The first API I tested - from Recreation.gov - could not have been more straightforward. It's an API that does not require authentication, so all I had to do was set the parameters to get the response I was looking for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---IaedwkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/PzjTGrZ/recreation-gov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---IaedwkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/PzjTGrZ/recreation-gov.png" alt="no auth method, screenshot of postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Reserve America API, on the other hand, did require authentication but only by way of an API key. This was as simple as signing up for a free developer account &amp;amp; adding the assigned API key as a parameter in my requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7YwEF0lU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/yk5qvBh/reserve-america.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7YwEF0lU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/yk5qvBh/reserve-america.png" alt="api key auth method, screenshot of postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dialing in on the connection between a user's input and the request that would then be sent off to the API took a couple of days to complete. What proved to be the most helpful / biggest takeaway from working with these two APIs within Postman was realizing I could &lt;strong&gt;&lt;em&gt;save all of my API requests to a collection&lt;/em&gt;&lt;/strong&gt;. Being able to save my spot where I left off to pick up at a later time was helpful in not needing to repeatedly reference the API docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YU7mIroZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/K9YL6QT/save-request.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YU7mIroZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/K9YL6QT/save-request.png" alt="saving requests workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What also helped me streamline my workflow was realizing I could &lt;strong&gt;&lt;em&gt;set my credentials as environmental variables&lt;/em&gt;&lt;/strong&gt;. This allowed me to not only securely store my credentials but also made them really easy to reuse across requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ec8Mi3Qw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/5jsNVh7/set-environment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ec8Mi3Qw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/5jsNVh7/set-environment.png" alt="where to find environment manager"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GFKvjvuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/1QWqp5N/env-variables.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GFKvjvuR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/1QWqp5N/env-variables.png" alt="setting up env variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pasting my API key into the parameters of my requests to the Reserve America API was not the most tedious I've done in my coding journey, but once I started working with a third party API that required OAuth 2.0, I knew I needed to figure out a more efficient method. &lt;/p&gt;

&lt;p&gt;Whereas an API key will generally remain the same for a project, OAuth2.0 requires that you use a client id &amp;amp; secret (password) to obtain an access token which will then grant you access to an API's data. The API dictates the amount of time an access token is valid for, so when testing an API that requires OAuth 2.0, it’s likely that you’ll have to frequently request a new access token. While I knew that, in my code, I'd have to figure out how to run two requests for the authorization flow (a POST request to receive access token that would allow me to send a GET request to receive music data), I appreciate that Postman simplifies this process for you while in testing. Navigating over to the 'Authorization' and selecting OAuth2.0 prompted me to set up the required information to gain an access token, and while I had to get a new access token every hour I was testing, it was not a huge inconvenience as Postman holds on to that required information for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iN883i3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/Q939s4K/access-token-generator.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iN883i3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/Q939s4K/access-token-generator.png" alt="oauth2.0 access token"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AwryGQBZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/Qm60Mcm/access-token-info.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AwryGQBZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/Qm60Mcm/access-token-info.png" alt="setting up access token"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💭 &lt;strong&gt;Final reflections&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;While you will probably never find me fretting about the hours I've wasted in my life doing x, y, and z and/or trying out the latest productivity hack, I've got to hand it to Postman for offering such a simple solution to API testing optimization as it has really allowed me to find my flow when setting up a new project. It is my hope, dear reader, that this post has demystified for you the magical tool that is Postman and that you feel a bit more equipped to process some data. Ciao.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>productivity</category>
      <category>testing</category>
    </item>
    <item>
      <title>Node.js &amp; the Promise That Callback Hell Can Be Avoided</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Tue, 15 Sep 2020 05:05:02 +0000</pubDate>
      <link>https://dev.to/jessrichmond/node-js-the-promise-that-callback-hell-is-not-inevitable-22jh</link>
      <guid>https://dev.to/jessrichmond/node-js-the-promise-that-callback-hell-is-not-inevitable-22jh</guid>
      <description>&lt;p&gt;Last week we saw an introduction to databases and servers where we were introduced to Node.js - an open source runtime envrionment that provides Javascript web developers with tools to talk to networks, file systems, and other input/output (I/O) sources. &lt;/p&gt;

&lt;p&gt;We learned that one of the key features of Node.js is the ability to run functions &lt;em&gt;asynchronously&lt;/em&gt;. Whereas the vanilla Javascript training wheels we’ve been rolling often had us reading a file of code from top to bottom without moving on to the next function until the current function is finished running, Node.js gives us the opportunity to work on a bunch of different functions all at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Real World Multitasking ≈ Async Javascript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s look at a real world example that highlights the importance of this sort of multitasking: going to the DMV. It’s almost always an objectively unpleasant experience, but can you imagine how much more awful it would be if the DMV did not sort folks into categories and instead just took care of people in the order that they arrived? When some people come into the DMV they are there to get a driver’s license for the first time, register their vehicle, get temporary tags, etc! Each of these services takes a different amount of time to execute, so instead of making everyone wait in relation to the order in which they arrived, the DMV recognizes that it’s more efficient to first categorize the services they provide and then give people a place in line based on what they came in for. &lt;/p&gt;

&lt;p&gt;Node.js does almost this exact same thing, except in a Javascript file. Instead of reading lines of code from top to bottom and waiting for one line to finish executing before moving on to the next, Node.js does not block the request thread and instead operates asynchronously.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Non-blocking Functions &amp;amp; Callbacks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Callbacks&lt;/em&gt; are what allow Node.js to operate this way; they’re used when doing any sort of I/O service ie downloading files, reading files, talking to databases. Our vanilla Javascript training has introduced us to functions that immediately return a result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const greeting = () =&amp;gt; {
  console.log('hello!');
}

greeting(); // 'hello!'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Functions that use callbacks, however take some time to produce a result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const greeting = 'hello,';

const personalizedGreeting = (greeting, callback) =&amp;gt; {
  if (err) {
    console.log('oops, an error.');
  } else {
    callback(greeting);
  }
};

personalizedGreeting(greeting, hiBetty);

function hiBetty (err, message) {
  if (err) {
    console.log('there is an error...');
  } else {
    console.log(`${message} betty the dog!`);
  }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Important to understanding Node.js is understanding that functions are allowed to jump around based on completion. In the above example, the hiBetty function is declared &amp;amp; hoisted (that is why we will not get a reference error); the personalizedGreeting function is invoked and passed getName as its callback; once getName has completed, the interpreter will print to the console, “hello Betty the dog”.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Entering the Realm of Callback Hell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now, this is a pretty readable code but I/O operations are not usually this simple. Let’s say that instead of simply printing to the console when Betty the dog logs in, I want to check if her online portal is complete? Did she sign up with a name, a photo, her health records, and daily schedule? Let's see...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const profileComplete = (dog, callback) =&amp;gt; {
  // is name attached to profile?
  isNameLoaded(dog, (err, loaded) =&amp;gt; {
    if (err) {
      callback(err, null);
    } else if (!loaded) {
      callback('enter your name!', null);
    } else {
      // if name is attached, is photo attached?
      isPhotoUploaded(dog, (err, uploaded) =&amp;gt; {
        if (err) {
          callback(err, null);
        } else if (!uploaded) {
          callback('upload a photo!', null);
        } else {
          // are health records online?
          checkHealthRecords(dog, (err, available) =&amp;gt; {
            if (err) {
              callback(err, null);
            } else if (!available) {
              callback('please upload your health records', null);
            } else {
              // is daily schedule online?
              isScheduleAttached(dog, (err, attached) =&amp;gt; {
                if (err) {
                  callback(err, null);
                } else if (!attached) {
                  callback('add your daily schedule!', null);
                } else {
                  callback(null, attached);
                }
              })
            }
          })
        }
      })
    }
  })
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This code hurts the eyes and writing this code hurt the brain. Do you see how the code gradually extends to the right? This is what ppl who code affectionately call the pyramid of doom aka the defining characteristic of 🔥 &lt;strong&gt;&lt;em&gt;callback&lt;/em&gt;&lt;/strong&gt; 🔥 &lt;strong&gt;&lt;em&gt;hell&lt;/em&gt;&lt;/strong&gt; 🔥.&lt;/p&gt;

&lt;p&gt;There are a handful of ways to get around callback hell. You can do as callbackhell.com suggests: keep your code shallow, modularize your functions, and handle every single error. The other option is to level UP and learn how to implement 🤞🏼 &lt;strong&gt;&lt;em&gt;promises&lt;/em&gt;&lt;/strong&gt; 🤞🏼.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Making Promises in Async Functions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Introduced in ES6, promises are Javascript objects that link producing code and consuming code. With promises, there’s an agreement that one function will execute once another function has been completed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const funcName = new Promise((resolve, reject) =&amp;gt; {...});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The function that is passed to a new Promise is an “executor”… it encapsulates a function that will eventually return a result. When the executor returns the result, it will then call ‘resolve’ with the value or “reject” with an error. If the executing function resolves to a value rather than being rejected as an error, its return value can be registered using handlers such as ‘.then’, ‘.catch’, and ‘.finally’; ‘.then’ continues on the passing along of resolved values, ‘.catch’ takes care of any errors that may pop up, and ‘.finally’ is a good for doing cleanup as it’ll stop any loading indicators.&lt;/p&gt;

&lt;p&gt;Now let’s take a look at our previous example but refactored to include promises.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const profileComplete = (dog) =&amp;gt; {
  return isNameLoaded(dog)
    .then((dog) =&amp;gt; {
      return isPhotoUploaded(dog);
    })
    .then((dog) =&amp;gt; {
      return checkHealthRecords(dog);
    })
    .then ((dog) =&amp;gt; {
      return isScheduleAttached(dog)
    })
    .catch((err) =&amp;gt; {
     return console.log('an error has occurred.')
    });
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;See, way easier to follow along! Promises are maybe, at this point of our coding journey, not the most intuitive functions to construct but it’s important to begin getting in the habit of making code more universally understandable as it is teamwork that makes the dream work.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Glimpse Into Back End Data Encryption: Schemes, Protocols, and Breadth</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Mon, 07 Sep 2020 06:15:31 +0000</pubDate>
      <link>https://dev.to/jessrichmond/a-glimpse-into-back-end-data-encryption-schemes-protocols-and-breadth-54e3</link>
      <guid>https://dev.to/jessrichmond/a-glimpse-into-back-end-data-encryption-schemes-protocols-and-breadth-54e3</guid>
      <description>&lt;p&gt;Encryption refers to the encoding of data. As data is sent and transferred from a user to a server, algorithms encrypt data and decrypt the data once it has reached the intended destination. The only way for the data to be decrypted is if that destination provides the proper key. The process of encryption can happen in so many different ways; first we’ll explore the two types of encryption and a couple of protocols &amp;amp; then we’ll take a look at the implications of a few real world examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Symmetric &amp;amp; Asymmetric Encryption&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are two leading schemes of encryption: symmetric and asymmetric. &lt;strong&gt;&lt;em&gt;Symmetric encryption&lt;/em&gt;&lt;/strong&gt; requires both the sender and receiver to have the same key. When both the sender and receiver have the same key, the algorithm is able to use the same method to encrypt &amp;amp; decrypt and thus is able to process more quickly. However, what must be considered is what happens if the recipient does not have the key… because the key must be sent to them, the key is vulnerable to being intercepted. This is why symmetric encryption is best for use within small, closed networks. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BOuWvOtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ssl2buy.com/wiki/wp-content/uploads/2015/12/Symmetric-Encryption.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BOuWvOtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ssl2buy.com/wiki/wp-content/uploads/2015/12/Symmetric-Encryption.png" alt="Symmetric encryption"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Asymmetric encryption&lt;/em&gt;&lt;/strong&gt;, on the other hand, operates a bit slower but is considered to be more secure. This method utilizes a public key in addition to a private key. It is the public key that encrypts the data... everybody has access to the public key. The only way to decrypt the data, though, is to have access to the private key. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ulZFrBZg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ssl2buy.com/wiki/wp-content/uploads/2015/12/Asymmetric-Encryption.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ulZFrBZg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ssl2buy.com/wiki/wp-content/uploads/2015/12/Asymmetric-Encryption.png" alt="Asymmetric encryption"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These schemes are deployed within a wide range of cryptographic protocols; each protocol has its own set of rules and methods to determine the functioning of an algorithm. The two you've probably encountered most frequently are Transport Layer Security and Secure Shell.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;TLS &amp;amp; SSH: Examples of Encryption Protocols&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Formerly known as Secure Sockets Layer (SSL), &lt;strong&gt;&lt;em&gt;Transport Layer Security (TLS)&lt;/em&gt;&lt;/strong&gt; provides a secure connection between a client and a website's server. The connection between a client and a server begins with a TLS 'handshake' in which asymmetric encryption is used to establish a session-specific key. Once the connection is established, data is transferred via symmetric encryption. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FgwsJE_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://external-content.duckduckgo.com/iu/%3Fu%3Dhttps%253A%252F%252Fblog.cloudflare.com%252Fcontent%252Fimages%252F2016%252F09%252FTLS-1.3.007.png%26f%3D1%26nofb%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FgwsJE_H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://external-content.duckduckgo.com/iu/%3Fu%3Dhttps%253A%252F%252Fblog.cloudflare.com%252Fcontent%252Fimages%252F2016%252F09%252FTLS-1.3.007.png%26f%3D1%26nofb%3D1" alt="TLS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Secure Shell (SSH)&lt;/em&gt;&lt;/strong&gt; allows for network services to be accessed over unsecured networks, and is often used to log into platforms. SSH does this by using asymmetric encryption to authenticate a remote network and consequently its user; all that is needed for authentication is a matching public-private key pair.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_GyIghIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://external-content.duckduckgo.com/iu/%3Fu%3Dhttps%253A%252F%252Fcloud.addictivetips.com%252Fwp-content%252Fuploads%252F2017%252F12%252FSSH-Tunneling.png%26f%3D1%26nofb%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_GyIghIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://external-content.duckduckgo.com/iu/%3Fu%3Dhttps%253A%252F%252Fcloud.addictivetips.com%252Fwp-content%252Fuploads%252F2017%252F12%252FSSH-Tunneling.png%26f%3D1%26nofb%3D1" alt="SSH"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Ok, but Encrypted To Which Point?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Encryption protocols all provide secure connections; however, maybe more important is in which direction that connection is secure. Let's place this into context by exploring something  that is pretty crucial to our current reality as people living in social isolation: messaging services! They're essential to staying connected these days! Sending a message to someone, whether it is over Facebook, Zoom, Slack, WhatsApp, Signal etc, requires a connection between one user, a server, and another user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8dE1uATz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.pikpng.com/pngl/m/49-494435_1600-x-321-9-1-whatsapp-viber-imo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8dE1uATz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.pikpng.com/pngl/m/49-494435_1600-x-321-9-1-whatsapp-viber-imo.png" alt="Messaging"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;&lt;em&gt;client-to-server encryption&lt;/em&gt;&lt;/strong&gt;, servers are able to decrypt &amp;amp; store the data it's received from the client. Because that data is sitting decoded in a database, it is susceptible to being intercepted by someone it was not intended for. Think attackers, internet service providers, governments surveilling citizens. When we're sending a message over Slack or Zoom or Facebook, that message is being stored in plaintext on Slack's servers and can be accessed by someone that message was not intended for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JUjMuUdb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/4jyQFgP/Screen-Shot-2020-09-07-at-12-34-52-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JUjMuUdb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/4jyQFgP/Screen-Shot-2020-09-07-at-12-34-52-AM.png" alt="C2S"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;End-to-end encryption&lt;/em&gt;&lt;/strong&gt;, on the other hand, is designed to where the data being sent is only available to the person who is receiving it. The server does not decode the information, generally stores little metadata on the transfer, and simply acts as a traffic router. Examples of this would be Signal, Discord, or WhatsApp.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3708xr8Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/7gk3yq2/Screen-Shot-2020-09-07-at-12-35-01-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3708xr8Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/7gk3yq2/Screen-Shot-2020-09-07-at-12-35-01-AM.png" alt="E2EE"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 🌐 📡 🔗 🌐 📡 🔗 🌐 📡 🔗 🌐 📡 🔗 🌐 📡
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In conclusion&lt;/em&gt;&lt;/strong&gt;, plenty of folks have never even considered what happens to the data they shoot into the world wide web and its subsidiaries. As we head into learning about servers and databases, it is my hope that this post was able to prime you with some of the fundamentals of data encryption.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Sinon.js Spies &amp; Stubs in Javascript Unit Testing</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Mon, 31 Aug 2020 05:12:02 +0000</pubDate>
      <link>https://dev.to/jessrichmond/using-sinon-js-spies-stubs-in-javascript-unit-testing-440b</link>
      <guid>https://dev.to/jessrichmond/using-sinon-js-spies-stubs-in-javascript-unit-testing-440b</guid>
      <description>&lt;p&gt;Say you've been tasked with an objective and have spent a significant amount of time constructing Javascript code that you assume will result in your desired output. How can you know for sure? You could just push that code into production and wait for the bug reports to roll in, oooor you could take a more proactive approach and test as you go for any potential issues while in development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/26tn33aiTi1jkl6H6/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/26tn33aiTi1jkl6H6/source.gif" alt="Coding GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you choose this route (honestly, as you should), you'll need to familiarize yourself with automated tests. When written properly, tests can give developers an idea of where their code might break. There are a different few types of automated tests, but here we'll be touching on &lt;em&gt;unit tests&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;the utility of unit tests&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As budding software developers putting our newfound knowledge into practice via sprints and toy problems, we are often evaluating the efficacy of our code by way of unit tests. Just as you might imagine, these tests evaluate units, or small chunks, of code. With unit tests (as opposed to, say, functional or integrated), we're often checking if a function is running as intended.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AAjzNu2g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mochajs.org/static/reporter-html.resize920%2C9999-withoutEnlargement.e2b1172cb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AAjzNu2g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://mochajs.org/static/reporter-html.resize920%2C9999-withoutEnlargement.e2b1172cb9.png" alt="Mocha test runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a &lt;em&gt;bunch&lt;/em&gt; of Javascript unit test frameworks out there, but in this post we'll be touching on some of the ins and outs of &lt;a href="https://sinonjs.org/"&gt;Sinon.js&lt;/a&gt;, which offers "standalone test spies, stubs, and mocks [that also] works with any unit testing framework".&lt;/p&gt;

&lt;p&gt;When dipping your toes into the waters of unit testing, it may be hard to conceptualize how to test code that depends on complex and dynamic external sources, such as servers or databases. We don't want to be sending requests to those servers or databases with every test we run, so it's important to figure out a way to simplify complex functions for the sake of testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;... cue Sinon!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/8db2748b2b99e495d932058ec2af35f28a66af12/68747470733a2f2f73696e6f6e6a732e6f72672f6173736574732f696d616765732f6c6f676f2e706e67" class="article-body-image-wrapper"&gt;&lt;img src="https://camo.githubusercontent.com/8db2748b2b99e495d932058ec2af35f28a66af12/68747470733a2f2f73696e6f6e6a732e6f72672f6173736574732f696d616765732f6c6f676f2e706e67" alt="Sinon.js logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sinon offers an answer to this issue by allowing programmers to create "test-doubles," that is ephemeral replacements for chunks of code. These test-doubles replace specific functions during test time, and can be configured in a multitude of ways. &lt;/p&gt;

&lt;p&gt;There are three types of test-doubles in Sinon: &lt;em&gt;spies&lt;/em&gt;, &lt;em&gt;stubs&lt;/em&gt;, and &lt;em&gt;mocks&lt;/em&gt;. Because mocks are essentially spies and stubs packaged into one, we'll be reviewing here the contrast between those building blocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;the spies and stubs of Sinon.js&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sinon spies&lt;/strong&gt; gather info about function calls. Spies can be used to verify whether or not a function was called, the number of times the function was called, the arguments that were passed in at call time, and then also the return value of that function call.&lt;/p&gt;

&lt;p&gt;Here's an example of a Sinon spy some of you may recognize. This spy is verifying that a function, Parse.create();, is being called after a form's submit button is clicked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sinon.spy(Parse, 'create');
App.initialize();
$('#message').val('Why so many Mel Brooks quotes?');
$('form .submit').trigger('submit');
expect(Parse.create.called).to.be.true;
Parse.create.restore();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One takeaway here is that Sinon spies rely on the original function running. &lt;strong&gt;Sinon stubs&lt;/strong&gt;, on the other hand, go one step further by not only spying on what a function does, but also by completely replacing the original function during the test. Take our earlier example of having a block of code that is requesting information from external sources. Testing that function as it is would slow down our processing time as well as burden our external sources with unimportant data. Substituting the function with a stub would sufficiently avoid that. Here's an example from the &lt;a href="https://sinonjs.org/releases/v9.0.3/stubs/"&gt;Sinon.js documentation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("stub", function() {
    it("should behave differently on consecutive calls", function() {
        const callback = sinon.stub();
        callback.onCall(0).returns(1);
        callback.onCall(1).returns(2);
        callback.returns(3);

        assert.equals(callback(), 1); // Returns 1
        assert.equals(callback(), 2); // Returns 2
        assert.equals(callback(), 3); // All following calls return 3
    });
});

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



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jl4CO2mf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/mvwnpRT/png-transparent-unit-testing-software-testing-test-automation-javascript-apache-cordova-potential-di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jl4CO2mf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/mvwnpRT/png-transparent-unit-testing-software-testing-test-automation-javascript-apache-cordova-potential-di.png" alt="JS Testing Flow Chart"&gt;&lt;/a&gt;&lt;br&gt;
Of course you shall learn more about automated testing frameworks as you progress through your coding journey &amp;amp; encounter various projects with their unique objectives, but it is my hope that after reading this post you have deepened your understanding of the unit tests that you'll often face as a student of software development.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exploring the Nuances of JavaScript Arrow Functions &amp; Why We Love 'Em</title>
      <dc:creator>jessrichmond</dc:creator>
      <pubDate>Mon, 24 Aug 2020 07:00:56 +0000</pubDate>
      <link>https://dev.to/jessrichmond/exploring-the-nuances-of-javascript-arrow-functions-why-we-love-em-322e</link>
      <guid>https://dev.to/jessrichmond/exploring-the-nuances-of-javascript-arrow-functions-why-we-love-em-322e</guid>
      <description>&lt;p&gt;When I was first introduced to JavaScript arrow functions, I understood them to be a shinier version of traditional function syntax. Sure, it made sense that as time went on, EcmaScript (ES) would have to update and adapt to new problems that developers aimed to solve, BUT I (naively) figured any sort of revision on an already existing feature was purely for aesthetics.&lt;/p&gt;

&lt;p&gt;However, as I spend more and more time coding, I’m realizing these updates are far more nuanced than my baby programmer brain could initially wrap my head around, and I'm excited to share this with you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ok! So functions. What are they?
&lt;/h1&gt;

&lt;p&gt;We know that functions allow us to execute a particular block of code whenever we want. We create the function via declaration or expression, we pass in an input (though not necessarily always), and then we invoke the function to produce an output.&lt;/p&gt;

&lt;p&gt;Classic function syntax requires a 'function' keyword, a set of parenthesis to hold your parameters, and a block of code encapsulated by curly brackets. Let's take a look at an example function that helps us figure out the current price of an item on sale implemented in this traditional function style:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J96ue3Nf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uskvkbsj170ach9hfdxa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J96ue3Nf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uskvkbsj170ach9hfdxa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Arrow function syntax&lt;/em&gt;&lt;/strong&gt;, on the other hand, does not require the 'function' keyword &amp;amp; only really requires a '=&amp;gt;' and a placeholder for parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--akf0TYoH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n1v5mceavrjfkoy2uhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--akf0TYoH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n1v5mceavrjfkoy2uhc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gAkwUw0H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.makeagif.com/media/7-18-2015/tIdIbJ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gAkwUw0H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.makeagif.com/media/7-18-2015/tIdIbJ.gif" alt="GIF from Me and You and Everyone We Know"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other than those two default requirements, arrow functions are able to take syntax simplification even further! Let's dive into a couple of specific situations that allow you to personalize stylization.&lt;/p&gt;

&lt;h4&gt;
  
  
  - If your function has no parameters...
&lt;/h4&gt;

&lt;p&gt;Demonstrate this with a pair of empty parenthesis or an underscore!&lt;/p&gt;

&lt;h4&gt;
  
  
  - If your function is one line...
&lt;/h4&gt;

&lt;p&gt;Curly brackets are not needed and neither is a return statement!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nGJILsiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h2dz4vl550b51i7fxs35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nGJILsiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h2dz4vl550b51i7fxs35.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  - If your function has one parameter...
&lt;/h4&gt;

&lt;p&gt;It is up to you to determine your preference for setting up the parameter inside a pair of parenthesis or without any at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w0jCWj3I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hmnkcvx2y2z5lqedepui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w0jCWj3I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hmnkcvx2y2z5lqedepui.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  - Otherwise...
&lt;/h4&gt;

&lt;p&gt;If your function has multiple parameters, parentheses are required, and/or if your function spans multiple lines, you'll need to encapsulate it in curly braces in addition making your return statement explicit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--akf0TYoH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n1v5mceavrjfkoy2uhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--akf0TYoH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6n1v5mceavrjfkoy2uhc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Now! That's enough about syntax. Arguably more interesting is how arrow functions interact with the keyword &lt;em&gt;this&lt;/em&gt;.
&lt;/h2&gt;

&lt;p&gt;The above examples are pretty simple implementations of JavaScript functions. However, as you progress through your coding journey, you'll come to encounter functions stored inside of other blocks of code, and you'll also be exposed to the usage of the &lt;em&gt;this&lt;/em&gt; keyword.&lt;/p&gt;

&lt;p&gt;In classic function expressions, the binding of &lt;em&gt;this&lt;/em&gt; changes in relation to the context it is called in. Check out the code below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LChSHt2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyt0bqw3bkz7bylz13is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LChSHt2n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyt0bqw3bkz7bylz13is.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you'd expect the result of invoking popStar.displaySingles(); in the above code to be the singles from Britney Spears' hit album, "Oops!...I Did It Again" (2000) logged to the console, BUT...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wt60vH25--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thumbs.gfycat.com/AgedComfortableAtlanticspadefish-size_restricted.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wt60vH25--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thumbs.gfycat.com/AgedComfortableAtlanticspadefish-size_restricted.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Didn't you remember that &lt;em&gt;this&lt;/em&gt;, as &lt;a href="https://www.freecodecamp.org/news/learn-es6-the-dope-way-part-ii-arrow-functions-and-the-this-keyword-381ac7a32881/"&gt;Mariya Diminsky over at FreeCodeCamp explains&lt;/a&gt;, "always references the owner of the function it is in"? The keyword &lt;em&gt;this&lt;/em&gt;, inside of an object, will refer to its parent object, but if &lt;em&gt;this&lt;/em&gt; is inside of a classic function expression, it will then refer to the global window object. So, when we invoke the above code, we will print to the console the following because the global window object does not have a .name property:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2LHMI9k3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1imfo0rm1oe13gptou6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2LHMI9k3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1imfo0rm1oe13gptou6s.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a couple of ways to get around this issue in ES5 (check out the FreeCodeCamp article for examples), but ES6 -- the most recent major update to EcmaScript -- provided a straightforward solution: &lt;strong&gt;&lt;em&gt;arrow functions&lt;/em&gt;&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uje06C0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/xT9DPmOJ1T72sStROo/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uje06C0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/xT9DPmOJ1T72sStROo/source.gif" alt="Broad City GIF: Dis Good"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arrow functions were designed so that the binding of &lt;em&gt;this&lt;/em&gt; is lexically scoped. This means &lt;em&gt;this&lt;/em&gt; will always refer to the block of code that the arrow function is declared in.&lt;/p&gt;

&lt;p&gt;If we revise the .displaySingles property on the popStar object to be an arrow function, we'll be able to print our desired output to the console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZWifxdSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uxx4rryk8t6upd0l9785.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZWifxdSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uxx4rryk8t6upd0l9785.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;center&gt; 👏🏼 👏🏼 👏🏼 👏🏼 👏🏼 👏🏼 &lt;/center&gt;
&lt;/h1&gt;

&lt;p&gt;All is well now in our popStar object, but! Don't go thinking that arrow functions and classic functions are completely interchangeable. Arrow functions do have a couple of downsides and we shall explore those another time! Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>thiskeyword</category>
    </item>
  </channel>
</rss>
