<?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: Feldroy</title>
    <description>The latest articles on DEV Community by Feldroy (@feldroy).</description>
    <link>https://dev.to/feldroy</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%2Forganization%2Fprofile_image%2F2038%2F85b94281-1fd3-4d6b-a488-4905d0180c3f.png</url>
      <title>DEV Community: Feldroy</title>
      <link>https://dev.to/feldroy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/feldroy"/>
    <language>en</language>
    <item>
      <title>Codecast #6: Writing Two Scoops of Django</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Wed, 08 Jul 2020 01:08:45 +0000</pubDate>
      <link>https://dev.to/feldroy/codecast-6-writing-two-scoops-of-django-44o3</link>
      <guid>https://dev.to/feldroy/codecast-6-writing-two-scoops-of-django-44o3</guid>
      <description>&lt;p&gt;Ever wanted to know how we update &lt;a href="https://www.feldroy.com/products/two-scoops-of-django-3-x"&gt;Two Scoops of Django&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;I recorded 4 hours of doing just that and uploaded it to YouTube. Let me know what you think!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/tnJFu5GvZyE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>writing</category>
      <category>books</category>
    </item>
    <item>
      <title>Codecast #4</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Thu, 02 Jul 2020 22:49:52 +0000</pubDate>
      <link>https://dev.to/feldroy/codecast-4-58ji</link>
      <guid>https://dev.to/feldroy/codecast-4-58ji</guid>
      <description>&lt;p&gt;For a while now I've been live streaming my coding sessions. Here's my latest coding session, where I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a SaaS product (Writernaut)&lt;/li&gt;
&lt;li&gt;Update an Async Django project&lt;/li&gt;
&lt;li&gt;Refactor tests written in PyTest&lt;/li&gt;
&lt;li&gt;Use Tailwindcss and TailwindUI to make a killer landing page&lt;/li&gt;
&lt;li&gt;Twiddle with AlpineJS&lt;/li&gt;
&lt;li&gt;Update my &lt;a href="https://www.feldroy.com/products/django-crash-course"&gt;Django Crash Course&lt;/a&gt; book&lt;/li&gt;
&lt;li&gt;Talk about my upcoming &lt;a href="https://www.feldroy.com/blogs/news/july-16th-and-17th-django-crash-course-live-online-class"&gt;live, online Django training taking place on July 16th and 17th&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you like my video, please like and subscribe!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/d75qfL-4RLg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you'd like to see more of my videos, &lt;a href="https://www.youtube.com/c/DanielFeldroy"&gt;head over to YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A quick way to detect bad practices on a Dockerfile</title>
      <dc:creator>Fábio C. Barrionuevo da Luz</dc:creator>
      <pubDate>Tue, 28 Apr 2020 17:08:40 +0000</pubDate>
      <link>https://dev.to/feldroy/a-quick-way-to-detect-bad-practices-on-a-dockerfile-41dl</link>
      <guid>https://dev.to/feldroy/a-quick-way-to-detect-bad-practices-on-a-dockerfile-41dl</guid>
      <description>&lt;p&gt;In Feldroy we use Docker images as the base to running the tools to build the PDF, EPUB, and Kindle files from the content written by &lt;a class="comment-mentioned-user" href="https://dev.to/audreyfeldroy"&gt;@audreyfeldroy&lt;/a&gt;
 and &lt;a class="comment-mentioned-user" href="https://dev.to/danielfeldroy"&gt;@danielfeldroy&lt;/a&gt;
.&lt;/p&gt;

&lt;p&gt;Having a 100% functional Dockerfile that follows good practices is a good thing to have.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://hadolint.github.io/hadolint/"&gt;&lt;code&gt;hadolint&lt;/code&gt;&lt;/a&gt; is a linter tool that helps to validate a Dockerfile to build Docker images that follow the recommendations of the &lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"&gt;&lt;code&gt;Best practices for writing Dockerfiles&lt;/code&gt;&lt;/a&gt; guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick way to use
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm -i hadolint/hadolint &amp;lt; Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What is the validation rules
&lt;/h2&gt;

&lt;p&gt;The validation follows these rules: &lt;a href="https://github.com/hadolint/hadolint#rules"&gt;https://github.com/hadolint/hadolint#rules&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to customize the validation
&lt;/h2&gt;

&lt;p&gt;We can customize the validation by creating the &lt;code&gt;.hadolint.yaml&lt;/code&gt; file: &lt;a href="https://github.com/hadolint/hadolint#configure"&gt;https://github.com/hadolint/hadolint#configure&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to integrate on the CI Server
&lt;/h2&gt;

&lt;p&gt;There are several examples of how to use &lt;code&gt;hadolint&lt;/code&gt; on &lt;code&gt;CI servers&lt;/code&gt;: &lt;a href="https://github.com/hadolint/hadolint/blob/master/docs/INTEGRATION.md"&gt;https://github.com/hadolint/hadolint/blob/master/docs/INTEGRATION.md&lt;/a&gt;&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>docker</category>
      <category>dockerfile</category>
      <category>lint</category>
    </item>
    <item>
      <title>Turn a REST API into a GraphQL API</title>
      <dc:creator>Audrey Roy Greenfeld</dc:creator>
      <pubDate>Mon, 27 Apr 2020 06:46:18 +0000</pubDate>
      <link>https://dev.to/feldroy/turn-a-rest-api-into-a-graphql-api-50kf</link>
      <guid>https://dev.to/feldroy/turn-a-rest-api-into-a-graphql-api-50kf</guid>
      <description>&lt;p&gt;I really like working with GraphQL APIs. I like being able to get data in the shape I want, and using subscriptions to get it in realtime. This weekend I discovered that transforming a REST API into a GraphQL one is easier than it sounds.&lt;/p&gt;

&lt;p&gt;This is a walkthrough of turning one REST endpoint to GraphQL. Once you can do one, you can do more 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  The REST API Endpoint We'll Transform
&lt;/h2&gt;

&lt;p&gt;To keep things simple, we'll use a simple GET REST endpoint as our starting point:&lt;/p&gt;

&lt;p&gt;GET &lt;a href="https://pokeapi.co/api/v2/pokemon/pikachu/"&gt;https://pokeapi.co/api/v2/pokemon/pikachu/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's create a GraphQL endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the GraphQL Schema for a Pokemon Object
&lt;/h2&gt;

&lt;p&gt;First we define our GraphQL type for the Pokemon data we'll be returning from our new API endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Pokemon {
  id:       String!
  name:     String!
  base_experience:  Int!
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the sake of example, we're limiting the fields, but add more if you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the GraphQL Query Type
&lt;/h2&gt;

&lt;p&gt;Then we define a GraphQL query called &lt;code&gt;getPokemon&lt;/code&gt; that takes an &lt;code&gt;id&lt;/code&gt; and returns a &lt;code&gt;Pokemon&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Query {
  getPokemon(id: String!): Pokemon
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Define the Query Resolver
&lt;/h2&gt;

&lt;p&gt;When a &lt;code&gt;getPokemon&lt;/code&gt; GraphQL query comes in, under the hood of our resolver, we send a GET request to &lt;code&gt;/pokemon/&amp;lt;id&amp;gt;/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const resolvers = {
  Query: {
      getPokemon: async (_, { id }) =&amp;gt; {

          const response = await fetch(MY_REST_URL + '/pokemon/' + id + '/');
          return response.json();
      },
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try the Query in GraphQL Playground
&lt;/h2&gt;

&lt;p&gt;A copy of the above code is &lt;a href="https://glitch.com/edit/#!/audreyr-pokemon-remote-schema"&gt;editable here on Glitch&lt;/a&gt;, and running &lt;a href="https://audreyr-pokemon-remote-schema.glitch.me/"&gt;live here with interactive querying via GraphQL Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to GraphQL Playground and try the query we just created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  getPokemon(id: "pikachu"){
    id
    base_experience
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It responds with real data from PokeAPI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "getPokemon": {
      "id": "25",
      "base_experience": 112
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yay! As a practice exercise, try implementing another field besides &lt;code&gt;base_experience&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remix my Glitch app&lt;/li&gt;
&lt;li&gt;Add the field to the &lt;code&gt;Pokemon&lt;/code&gt; schema&lt;/li&gt;
&lt;li&gt;Add it to your query and see the results in GraphQL Playground&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z2FELErr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rkibazax5pwy70oqb38e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z2FELErr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rkibazax5pwy70oqb38e.jpg" alt="You Can Do It"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this knowledge and a little practice, there's so much you can do. Enjoy!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Autodocumenting Makefiles</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Sat, 25 Apr 2020 06:10:53 +0000</pubDate>
      <link>https://dev.to/feldroy/autodocumenting-makefiles-175b</link>
      <guid>https://dev.to/feldroy/autodocumenting-makefiles-175b</guid>
      <description>&lt;p&gt;Today was my 6th day of 100 days of code. I was working on the forthcoming &lt;a href="https://www.feldroy.com/collections/two-scoops-press/products/two-scoops-of-django-3-x"&gt;Two Scoops of Django 3.x&lt;/a&gt; and thanks to my co-worker Fabio I learned something new about Makefiles. This is an expansion on what he provided (I added the output list and sort feature).&lt;/p&gt;

&lt;h1&gt;
  
  
  Using PYSCRIPT to Print Documentation
&lt;/h1&gt;

&lt;p&gt;I've seen variations of this trick but this is the best version ever. At the top of your &lt;code&gt;Makefile&lt;/code&gt;, put in this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;.DEFAULT_GOAL&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;help&lt;/span&gt; &lt;span class="c"&gt;# Sets default action to be help&lt;/span&gt;

&lt;span class="err"&gt;define&lt;/span&gt; &lt;span class="err"&gt;PRINT_HELP_PYSCRIPT&lt;/span&gt; &lt;span class="c"&gt;# start of Python section
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt; &lt;span class="err"&gt;re,&lt;/span&gt; &lt;span class="err"&gt;sys&lt;/span&gt;

&lt;span class="nv"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;span class="c"&gt;# Loop through the lines in this file
&lt;/span&gt;&lt;span class="nl"&gt;for line in sys.stdin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="c"&gt;# if the line has a command and a comment start with&lt;/span&gt;
    &lt;span class="c"&gt;#   two pound signs, add it to the output&lt;/span&gt;
    match &lt;span class="o"&gt;=&lt;/span&gt; re.match&lt;span class="o"&gt;(&lt;/span&gt;r&lt;span class="s1"&gt;'^([a-zA-Z_-]+):.*?## (.*)$$'&lt;/span&gt;, line&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;match:
        target, &lt;span class="nb"&gt;help&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; match.groups&lt;span class="o"&gt;()&lt;/span&gt;
        output.append&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"%-20s %s"&lt;/span&gt; % &lt;span class="o"&gt;(&lt;/span&gt;target, &lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="c"&gt;# Sort the output in alphanumeric order
&lt;/span&gt;&lt;span class="err"&gt;output.sort()&lt;/span&gt;
&lt;span class="c"&gt;# Print the help result
&lt;/span&gt;&lt;span class="err"&gt;print(&lt;/span&gt;&lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="err"&gt;.join(output))&lt;/span&gt;
&lt;span class="err"&gt;endef&lt;/span&gt;
&lt;span class="k"&gt;export &lt;/span&gt;&lt;span class="err"&gt;PRINT_HELP_PYSCRIPT&lt;/span&gt; &lt;span class="c"&gt;# End of python section
&lt;/span&gt;
&lt;span class="nl"&gt;help&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;PRINT_HELP_PYSCRIPT"&lt;/span&gt; &amp;lt; &lt;span class="nv"&gt;$(MAKEFILE_LIST)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we added concise docstrings for every &lt;code&gt;Makefile&lt;/code&gt; command. Here's what we did for two of the commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="nf"&gt; Extracts code for uploading to GitHub&lt;/span&gt;
    python extractor.py

&lt;span class="nl"&gt;rmcode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;##&lt;/span&gt;&lt;span class="nf"&gt; Removes sample code &lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how each command's docstring starts with two pound signs? The "##"? That's what the auto documenter code needs to find the docstring.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trying it out!
&lt;/h1&gt;

&lt;p&gt;When I type just &lt;code&gt;make&lt;/code&gt; without any arguments, by default that triggers the &lt;code&gt;help&lt;/code&gt; function, which runs the Python script at the top of the makefile. What I get is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;make
clean                Cleans up the environment
cleandocker          Cleans up the docker environment
code                 Extracts code &lt;span class="k"&gt;for &lt;/span&gt;uploading to GitHub
dpdf                 Render PDF &lt;span class="k"&gt;in &lt;/span&gt;docker
mdeps                Discovers missing LaTeX deps
mint                 Production ebook rendering
print                Renders print version
rmcode               Removes sample code 
short                faster rendering with minimal index check
tiny                 even faster rendering with no index check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very useful!&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>100daysofcode</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Simple JavaScript Loops</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Fri, 24 Apr 2020 17:06:46 +0000</pubDate>
      <link>https://dev.to/feldroy/simple-javascript-loops-3lp</link>
      <guid>https://dev.to/feldroy/simple-javascript-loops-3lp</guid>
      <description>&lt;p&gt;In this, my 5th day of 100daysofcode, I'm writing a tutorial. This tutorial is a cookbook of my favorite JavaScript looping techniques and to a lesser degree, object introspection. It should prove useful to anyone new to JavaScript, especially if you are coming from languages with &lt;code&gt;for...in&lt;/code&gt; (python in particular). &lt;/p&gt;

&lt;p&gt;I'm doing this in my browser JavaScript console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looping for values
&lt;/h2&gt;

&lt;p&gt;Looping through elements of an array is easy in JavaScript. Use &lt;code&gt;for...of&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;for...of&lt;/code&gt; returns the value of the loop iteration. It's the right tool for this operation.&lt;/p&gt;

&lt;h1&gt;
  
  
  Looping for index
&lt;/h1&gt;

&lt;p&gt;If you need to track the index of a loop, do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This technique is reliable and acts predictably. I've heard that this method runs more quickly than &lt;code&gt;for...of&lt;/code&gt;, but JavaScript is very fast these days. Any slowdowns your code might have is probably due to latency or other bottlenecks rather than which JavaScript looping technique you choose to implement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the difference between &lt;code&gt;for...of&lt;/code&gt; and &lt;code&gt;for...in&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Let's use both techniques on the same array and see what we get. First, the &lt;code&gt;for...of&lt;/code&gt; combination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the &lt;code&gt;for...in&lt;/code&gt; combination, &lt;strong&gt;which isn't recommended&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It appears that &lt;code&gt;for...in&lt;/code&gt; returns the index of the loop iteration, right? What's wrong with that? &lt;/p&gt;

&lt;p&gt;Read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems using &lt;code&gt;for...in&lt;/code&gt; with arrays
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;for...in&lt;/code&gt; can fool you into thinking it's the right tool for iterating over arrays for indexes instead of the more verbose approach of &lt;code&gt;(let i=0; i &amp;lt; arr.length; i++)&lt;/code&gt;. This appeared to work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But let's change things up a bit with some prototype manipulation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;icecream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ice cream!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The array has been proven to have four elements. Now let's iterate over the array using &lt;code&gt;for...in&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="nx"&gt;icecream&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where did the &lt;code&gt;icecream&lt;/code&gt; value come from? &lt;code&gt;icecream&lt;/code&gt; function wasn't in the array but &lt;code&gt;for...in&lt;/code&gt; called it anyway. What just happened?!?&lt;/p&gt;

&lt;p&gt;What's going on is that the &lt;code&gt;for...in&lt;/code&gt; is enumerating over the &lt;strong&gt;properties&lt;/strong&gt; of the array, not the values or index. Even if you avoid using prototypes, the same cannot be said for any library installed from NPM. Finally, there is no guarantee that the elements will be returned &lt;code&gt;for...in&lt;/code&gt; in numeric order.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about &lt;code&gt;forEach&lt;/code&gt; loops?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;forEach&lt;/code&gt; loop requires a callback, making it a slightly advanced enough method of writing for loops in JavaScript. I'll cover that in a future article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;for...of&lt;/code&gt; for iterating over the values of an array.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;(let i=0; i &amp;lt; arr.length; i++)&lt;/code&gt; for enumerating over the index of an array.&lt;/li&gt;
&lt;li&gt;Avoid using &lt;code&gt;for...in&lt;/code&gt; for iterating over arrays in any capacity.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>cheatsheet</category>
    </item>
    <item>
      <title>JAMStack Fun: Combining StackBit, Forestry, Netlify, Gatsby, Hasura, Glitch</title>
      <dc:creator>Audrey Roy Greenfeld</dc:creator>
      <pubDate>Wed, 22 Apr 2020 08:21:06 +0000</pubDate>
      <link>https://dev.to/feldroy/jamstack-fun-combining-stackbit-forestry-netlify-gatsby-hasura-glitch-58g</link>
      <guid>https://dev.to/feldroy/jamstack-fun-combining-stackbit-forestry-netlify-gatsby-hasura-glitch-58g</guid>
      <description>&lt;p&gt;For days 6-7 of #100DaysOfCode, I did various &lt;a href="https://www.netlify.com/products/forms/"&gt;JAMStack&lt;/a&gt; experiments with SaaS and open-source tools, putting them together to see what would happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying Out Stackbit
&lt;/h2&gt;

&lt;p&gt;I signed up for a &lt;a href="https://www.stackbit.com/"&gt;Stackbit&lt;/a&gt; account and used their site builder to create a project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Theme: Azimuth&lt;/li&gt;
&lt;li&gt;Site generator: &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CMS: &lt;a href="https://forestry.io/"&gt;Forestry&lt;/a&gt; (Always wanted to try it!)&lt;/li&gt;
&lt;li&gt;Deployment: GitHub repository with Netlify build + deploy (the only current options available. I look forward to Gitlab coming soon!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I connected my Forestry and GitHub accounts.&lt;/p&gt;

&lt;p&gt;Stackbit says it deployed my site. Ooh, it's really live:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnLCGmCl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/afdfa3ahstpi4s0ift3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnLCGmCl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/afdfa3ahstpi4s0ift3o.png" alt="My deployed Stackbit static site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I clicked &lt;em&gt;Claim&lt;/em&gt; to claim the Netlify project. It worked, yay.&lt;/p&gt;

&lt;p&gt;Then I clicked &lt;em&gt;Edit in Forestry&lt;/em&gt; to edit the content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying Out Forestry
&lt;/h2&gt;

&lt;p&gt;Forestry provides a GUI for editing Gatsby content. It also supports Hugo, Gridsome, Jekyll, and other static site generators.&lt;/p&gt;

&lt;p&gt;It's pretty cool, and I could see it being useful for people who can't build their static site locally or are editing from a mobile device.&lt;/p&gt;

&lt;p&gt;The lag between updating a site via Forestry and seeing the new deployed version on Netlify was a few minutes. For my purposes, I find running &lt;code&gt;npm run develop&lt;/code&gt; easier because I can see the static site changes on localhost in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a Netlify Function
&lt;/h2&gt;

&lt;p&gt;Next I added a &lt;a href="https://www.netlify.com/products/functions/"&gt;Netlify function&lt;/a&gt;. Initially it'll do almost nothing, but I could see it implementing something dynamic and server-side like what you would expect of an Express or Django web application.&lt;/p&gt;

&lt;p&gt;I cloned the GitHub repo, then created a Netlify function by copying &lt;a href="https://kentcdodds.com/blog/super-simple-start-to-serverless"&gt;functions/hello.js&lt;/a&gt; by &lt;a class="mentioned-user" href="https://dev.to/kentcdodds"&gt;@kentcdodds&lt;/a&gt;
 into my project. I added it to my build in &lt;em&gt;netlify.toml&lt;/em&gt;. Then I git committed and then went to Netlify to watch the build go.&lt;/p&gt;

&lt;p&gt;Now that the function's deployed, it's here:&lt;br&gt;
&lt;a href="https://curious-rosemary-e8299.netlify.app/.netlify/functions/hello?name=Uma"&gt;https://curious-rosemary-e8299.netlify.app/.netlify/functions/hello?name=Uma&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whatever you pass into &lt;code&gt;name&lt;/code&gt; gets shown on the page by the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// functions/hello.js from https://kentcdodds.com/blog/super-simple-start-to-serverless&lt;/span&gt;
&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'd like to expand this into something real and maybe have it get triggered by a form submission via a &lt;a href="https://www.netlify.com/products/forms/"&gt;Netlify form&lt;/a&gt; like the &lt;code&gt;contactForm&lt;/code&gt; provided by the sample code. But in the interest of time, I'm saving that for another day to focus on getting the Gatsby site to display dynamic remote API data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimenting with Gatsby
&lt;/h2&gt;

&lt;p&gt;It's been years since I last used React, so getting Gatsby to do what I wanted was a challenge. My hope at this point was to replicate what a Django &lt;code&gt;ListView&lt;/code&gt; does in JAMstack.&lt;/p&gt;

&lt;p&gt;I created an &lt;code&gt;items.js&lt;/code&gt; page to play in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Hello!
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I looked into populating the page with dynamic data. If I could grab data onto this static page from a remote GraphQL endpoint, that would be great.&lt;/p&gt;

&lt;p&gt;Gatsby uses GraphQL, so I started with using that as test data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Items List &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;This is a static site, but it's loading items dynamically from GraphQL:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nav_links&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    site {
      siteMetadata {
        header {
          nav_links {
            label
          }
        }
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting Up a GraphQL API with Hasura
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hasura.io/"&gt;Hasura&lt;/a&gt; is an open-source, Heroku-deployable tool that can take existing databases and give you a GraphQL API. &lt;/p&gt;

&lt;p&gt;I did the first part of the Hasura tutorial and loved it. Now I have a &lt;em&gt;todos&lt;/em&gt; table I can query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query MyQuery {
  todos {
    id
    title
  }
}

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

&lt;/div&gt;



&lt;p&gt;The response from Hasura with my sample data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="err"&gt;":&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding a New Gatsby GraphQL Root
&lt;/h2&gt;

&lt;p&gt;I did an &lt;code&gt;npm install gatsby-source-graphql&lt;/code&gt; then added my Hasura GraphQL API to &lt;em&gt;gatsby-config.js&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;I see that the &lt;a href="https://www.gatsbyjs.org/docs/third-party-graphql/#basic-example"&gt;example from the Gatsby docs&lt;/a&gt; points at &lt;a href="https://api.graphcms.com/simple/v1/swapi"&gt;https://api.graphcms.com/simple/v1/swapi&lt;/a&gt; which is down. &lt;/p&gt;

&lt;p&gt;Looks like that site, &lt;a href="https://graphcms.com/"&gt;GraphCMS&lt;/a&gt;, was featured on ProductHunt today...I'll sign up and see if they have an updated sample endpoint. Hmm, it looks like an interesting rabbit hole for another day.&lt;/p&gt;

&lt;p&gt;In Hasura, I went to &lt;code&gt;Remote Schemas &amp;gt; *Try it with Glitch*&lt;/code&gt; and found &lt;a href="https://hasura-sample-remote-schema.glitch.me"&gt;hasura-sample-remote-schema.glitch.me/ &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;a class="mentioned-user" href="https://dev.to/danielfeldroy"&gt;@danielfeldroy&lt;/a&gt;
's help we added the new root to &lt;em&gt;gatsby-config.js&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;resolve:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gatsby-source-graphql"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;options:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;contain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;remote&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;typeName:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;under&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;which&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;accessible&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;fieldName:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hasuraSample"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="err"&gt;url:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://hasura-sample-remote-schema.glitch.me/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then he figured out this query worked in Glitch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  hello 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;a href="http://127.0.0.1:8000/___graphql"&gt;http://127.0.0.1:8000/___graphql&lt;/a&gt; we got this query to work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {hasuraSample {
  hello
}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Showing Remote GraphQL Data on a Gatsby Page
&lt;/h2&gt;

&lt;p&gt;Finally, I updated &lt;em&gt;items.js&lt;/em&gt; to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Items List&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;This is a static site, but it's loading items dynamically from GraphQL:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasuraSample&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {hasuraSample {
    hello
  }}
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that, &lt;a href="http://localhost:8000/items"&gt;http://localhost:8000/items&lt;/a&gt; now shows a static Gatsby page with the live data from the Glitch-hosted Hasura Sample Remote Schema!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lGn3qDXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wky9toai3mqr5vpjhl8j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lGn3qDXE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wky9toai3mqr5vpjhl8j.jpg" alt="JAMstack: Putting It All Together"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was really fun to play around and put all these JAMstack toys together, particularly the ones that auto-configured themselves and auto-deployed. Every piece served a purpose and did it well. That was cool!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gatsby</category>
      <category>graphql</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Day 4: Exploring async and await in JavaScript</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Tue, 21 Apr 2020 06:50:11 +0000</pubDate>
      <link>https://dev.to/feldroy/day-4-exploring-async-and-await-in-javascript-bo9</link>
      <guid>https://dev.to/feldroy/day-4-exploring-async-and-await-in-javascript-bo9</guid>
      <description>&lt;p&gt;I've always enjoyed the feeling of JavaScript promises, possibly because they feel more explicit than what I've read about &lt;code&gt;await&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt;. I've also used &lt;code&gt;await&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt; in Python, and have always wished async code there was implemented with JavaScript-style promises.&lt;/p&gt;

&lt;p&gt;However, a lot of JavaScript code is written with &lt;code&gt;await&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt;, so I decided to knuckle down and get familiar with them. &lt;/p&gt;

&lt;p&gt;First I defined a function that returned a promise and would take some time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;squareXAndWaitXSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// square the result&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// delay by x seconds&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I wrote an &lt;code&gt;async&lt;/code&gt; function to call the &lt;code&gt;squareXAndWaitXSeconds&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;squareXAndWaitXSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// await for the response&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Log the response&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this worked, it was hard to see it in action. So I used HTML for better display:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/tailwindcss@^1.2/dist/tailwind.min.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Playing with Await/Async&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Use an ordered list to display the results in order they appear --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ol&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"result"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-decimal px-10"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I modified the &lt;code&gt;addItem&lt;/code&gt; function to post the result in &lt;code&gt;li&lt;/code&gt; tags inside the ordered list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;squareXAndWaitXSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Show x  when it's done being awaited&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-green-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Returning &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; seconds`&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was much better, but I wanted a spread of numbers to evaluate. I used a &lt;code&gt;for...of&lt;/code&gt; loop to give me better insight into what was happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Count down from 5 so we can see that higher number values&lt;/span&gt;
&lt;span class="c1"&gt;// generate results after lower number values. Nothing blocks!&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;
  &lt;span class="c1"&gt;// Show we're testing "i" immediately&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-red-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Testing &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// run the addItem() function. It won't show until i second(s) pass.&lt;/span&gt;
  &lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In My Own Words: What's Happening
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;addItem()&lt;/code&gt; function is labeled &lt;code&gt;async&lt;/code&gt;, meaning that it won't block while it "waits" for the &lt;code&gt;await&lt;/code&gt; called function (&lt;code&gt;squareXandWaitXSeconds&lt;/code&gt;) to finish evaluating. The logic flow keeps going, hence &lt;code&gt;addItem()&lt;/code&gt; is an asynchronous function. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;setTimeout&lt;/code&gt; function is used here to test this capability. In other circumstances, this could be used to render complex data on a screen (including games), call an API, or access a database. &lt;/p&gt;

&lt;p&gt;You can see where I noodled this out in this codepen: &lt;iframe height="600" src="https://codepen.io/pydanny/embed/VwvKgqW?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>100daysofcode</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Day 5 of #100DaysOfCode: Dev.to Cover Image Generator</title>
      <dc:creator>Audrey Roy Greenfeld</dc:creator>
      <pubDate>Mon, 20 Apr 2020 06:45:41 +0000</pubDate>
      <link>https://dev.to/feldroy/day-5-of-100daysofcode-dev-to-cover-image-generator-2g6l</link>
      <guid>https://dev.to/feldroy/day-5-of-100daysofcode-dev-to-cover-image-generator-2g6l</guid>
      <description>&lt;p&gt;Tonight I created this cover image generator: &lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/audreyfeldroy/embed/rNOMxad?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;It uses JavaScript to draw on an HTML5 canvas.&lt;/p&gt;

&lt;p&gt;To change the text:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fork this on CodePen: &lt;a href="https://codepen.io/audreyfeldroy/pen/rNOMxad"&gt;https://codepen.io/audreyfeldroy/pen/rNOMxad&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In the JS panel, change the lines with &lt;code&gt;ctx.fillText&lt;/code&gt; to be the text you want.&lt;/li&gt;
&lt;li&gt;Break any long lines into two lines, or shrink the fonts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll probably also want to change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The colors&lt;/li&gt;
&lt;li&gt;The fonts&lt;/li&gt;
&lt;li&gt;The parameters of the fractal tree&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have fun! I'd love to see what you create, so please share your posts/forks in the comments below.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codepen</category>
      <category>meta</category>
      <category>html</category>
    </item>
    <item>
      <title>Day 3: Attaching Custom Exceptions to Functions and Classes in Python</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Mon, 20 Apr 2020 05:55:29 +0000</pubDate>
      <link>https://dev.to/feldroy/day-3-attaching-custom-exceptions-to-functions-and-classes-in-python-1igp</link>
      <guid>https://dev.to/feldroy/day-3-attaching-custom-exceptions-to-functions-and-classes-in-python-1igp</guid>
      <description>&lt;p&gt;Having too many custom exceptions on a project can be a pain, but a few choices are nice. The problem is that in complex libraries having to import both functions and exceptions becomes a drag. To mitigate having to remember to import custom exceptions, this is a handy pattern you can use in a project and can be done on both functions and classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attaching a Custom Exception to Functions
&lt;/h2&gt;

&lt;p&gt;This works because Python functions are first-class objects. They can be passed around as things, and in this case, have things assigned to them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# logic.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;""" Easy to understand naming conventions work best! """&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;""" This function only works on numbers."""&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function does not compute"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Assign DoesNotCompute exception to this_function
&lt;/span&gt;&lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can import the function, and it won't just throw &lt;code&gt;DoesNotCompute&lt;/code&gt; exceptions, it will also carry the function along with the import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;3125&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;869.8739233809259&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'will throw an error.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;input&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"logic.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, that doesn't seem like much, but let's add in some exception handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'is an example'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'See what attaching custom exceptions to functions can do?'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;See&lt;/span&gt; &lt;span class="n"&gt;what&lt;/span&gt; &lt;span class="n"&gt;attaching&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="n"&gt;exceptions&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;functions&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Attaching the Custom Exception to Classes
&lt;/h2&gt;

&lt;p&gt;All we have to do is enhance our existing &lt;code&gt;logic.py&lt;/code&gt; file by adding &lt;code&gt;ThisClass&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# logic.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;""" Easy to understand naming conventions work best! """&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# removed the function example for clarity
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThisClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Assign DoesNotCompute to this class
&lt;/span&gt;    &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s"&gt;""" This method only works on numbers."""&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Class does not compute"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to demonstrate in the shell (Python REPL for the semantic purists):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;51.415729444066585&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Don't create too many custom exceptions"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;input&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"logic.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this_method&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'I like ice cream'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Milk, ice, and fruit in a blender is nice too'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Milk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;blender&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;nice&lt;/span&gt; &lt;span class="n"&gt;too&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Admonition: Don't Go Crazy
&lt;/h1&gt;

&lt;p&gt;Rather than use this trick all over the place, considering using it in a few strategic places to powerful effect. For example, Django uses it only in a few places, and publicly only on &lt;code&gt;MyModelClass.DoesNotExist&lt;/code&gt; and &lt;code&gt;MyModelClass.MultipleObjectsReturned&lt;/code&gt;. By limiting Django's use of this technique, Django libraries are that much easier to comprehend. In this case, less complexity means more.&lt;/p&gt;

&lt;p&gt;I say this because this pattern lends itself to creating custom exceptions to the point of effectively replacing Python's stock exceptions with your own. This makes for harder-to-maintain and harder-to-learn projects.&lt;/p&gt;

&lt;p&gt;Not that I've ever done that. Ahem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updated 2020/04/20: Added missing &lt;code&gt;self&lt;/code&gt; in &lt;code&gt;ThisClass&lt;/code&gt; thanks to &lt;strong&gt;Chiheb Nexus Lad&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>100daysofcode</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Day 4 of #100DaysOfCode: Building My First Square App with Glitch</title>
      <dc:creator>Audrey Roy Greenfeld</dc:creator>
      <pubDate>Sun, 19 Apr 2020 00:25:44 +0000</pubDate>
      <link>https://dev.to/feldroy/day-4-of-100daysofcode-taking-orders-via-an-express-square-app-2d1l</link>
      <guid>https://dev.to/feldroy/day-4-of-100daysofcode-taking-orders-via-an-express-square-app-2d1l</guid>
      <description>&lt;p&gt;Today I built my first working Square app!&lt;/p&gt;

&lt;p&gt;I started with Square's official &lt;a href="https://github.com/square/connect-api-examples/tree/master/connect-examples/v2/node_orders-payments"&gt;Order-Ahead Sample App&lt;/a&gt;, a Node/Express project.&lt;/p&gt;

&lt;p&gt;Following its accompanying &lt;a href="https://developer.squareup.com/docs/orders-api/quick-start/start"&gt;tutorial in the Square docs&lt;/a&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;I created an Order Ahead app in &lt;a href="https://developer.squareup.com/apps/"&gt;https://developer.squareup.com/apps/&lt;/a&gt; (you need a &lt;a href="//squareup.com/i/EATSWADESH"&gt;Square account&lt;/a&gt; to do this)&lt;/p&gt;

&lt;p&gt;I updated &lt;code&gt;config.json&lt;/code&gt; with the sandbox app ID and token.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;npm test&lt;/code&gt; failed. I did &lt;code&gt;npm install&lt;/code&gt; and tried again. It worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm test

&amp;gt; order-ahead-sample-app@0.0.0 test /Users/arg/projects/3rd-party/connect-api-examples/connect-examples/v2/node_orders-payments
&amp;gt; NODE_ENV=sandbox node ./bin/www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  First Local Run
&lt;/h2&gt;

&lt;p&gt;I went to &lt;a href="http://localhost:3000/"&gt;http://localhost:3000/&lt;/a&gt; and saw a page with "Sandbox Location Business Nickname" at the top. Yay, the app runs locally!&lt;/p&gt;
&lt;h2&gt;
  
  
  Generating Test Data
&lt;/h2&gt;

&lt;p&gt;I ran the example script to seed the sandbox store catalog with test data. It generated a bunch of restaurant food items:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm run seed

&amp;gt; order-ahead-sample-app@0.0.0 seed /Users/arg/projects/3rd-party/connect-api-examples/connect-examples/v2/node_orders-payments
&amp;gt; NODE_ENV=sandbox node ./bin/script/seed-catalog.js generate

Successfully uploaded item: #Italian Sandwich
Successfully uploaded item: #Steak Tacos
Successfully uploaded item: #Autumn Soup
Successfully uploaded item: #Sunny-Side Egg on Toast
Successfully uploaded item: #Fried Chicken Sandwich
Successfully uploaded item: #Salmon with Zucchini
Successfully uploaded item: #Oatmeal with Fruit
Successfully uploaded item: #Mediterranean Yogurt Bowl
Successfully uploaded item: #Meatballs
Successfully uploaded item: #Pancakes with Fruit
Successfully uploaded item: #Bacon Cheeseburger
Successfully uploaded item: #Grilled Steak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Placing a Sample Order
&lt;/h2&gt;

&lt;p&gt;Restarting the local server with &lt;code&gt;npm test&lt;/code&gt;, I now see those test items. I can click them to see a pop-up with detail and a &lt;em&gt;Buy This&lt;/em&gt; button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w9-SoZh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zz6fqhg6bbuu0scbro3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w9-SoZh5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zz6fqhg6bbuu0scbro3h.png" alt="Detail pop-up for Fried Chicken Sandwich"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking &lt;em&gt;Buy This&lt;/em&gt; leads to &lt;em&gt;Choose Delivery Method&lt;/em&gt;:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Under &lt;em&gt;Delivery Method&lt;/em&gt;, the only option is &lt;em&gt;Pickup&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;em&gt;Pickup Location&lt;/em&gt;, the only option is &lt;em&gt;Sandbox Location Business Nickname&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next screen was &lt;em&gt;Review and Complete Your Order&lt;/em&gt;. I entered the &lt;a href="https://developer.squareup.com/docs/orders-api/quick-start/step-4"&gt;test card&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PnlRKJrs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zaaf3m3zyrh8ll0ecp3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PnlRKJrs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zaaf3m3zyrh8ll0ecp3d.png" alt="Review and Complete Your Order page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I clicked &lt;em&gt;Pay with Card&lt;/em&gt; and it gave me this &lt;em&gt;Order Confirmation&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lUsO9G8Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5571lbv42t29rof6tzvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lUsO9G8Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5571lbv42t29rof6tzvu.png" alt="Order Confirmation"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Verifying the Order in the Sandbox
&lt;/h2&gt;

&lt;p&gt;Sure enough, the order shows up under Orders:&lt;/p&gt;

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

&lt;p&gt;I can mark it &lt;em&gt;In Progress&lt;/em&gt;, then &lt;em&gt;Ready&lt;/em&gt;, then &lt;em&gt;Picked Up&lt;/em&gt; using the upper right button.&lt;/p&gt;

&lt;p&gt;That's great that the sample Square app works locally.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting It Running on Glitch
&lt;/h2&gt;

&lt;p&gt;I made a copy of the node_orders-payments folder as OrderAhead.&lt;/p&gt;

&lt;p&gt;I copied &lt;a href="https://github.com/github/gitignore/blob/master/Node.gitignore"&gt;GitHub's Node.gitignore&lt;/a&gt; as the project .gitignore.&lt;/p&gt;

&lt;p&gt;The code's now in a GitHub repo: &lt;a href="https://github.com/feldroy/OrderAhead"&gt;https://github.com/feldroy/OrderAhead&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Glitch, I clicked &lt;em&gt;New Project&lt;/em&gt; &amp;gt; &lt;em&gt;Clone from Git Repo&lt;/em&gt; and pasted in &lt;code&gt;git@github.com:feldroy/OrderAhead.git&lt;/code&gt;. The screen went black and it didn't like that. I tried again with &lt;a href="https://github.com/feldroy/OrderAhead.git"&gt;https://github.com/feldroy/OrderAhead.git&lt;/a&gt; and that worked.&lt;/p&gt;

&lt;p&gt;The Square tutorial had me put credentials into &lt;code&gt;config.json&lt;/code&gt; earlier, which I .gitignored. I moved those to &lt;code&gt;.env&lt;/code&gt; and now load them from there in &lt;code&gt;util/square-connect-client.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const config = {
  "path": "https://connect.squareupsandbox.com",
  "squareApplicationId": process.env.SQUARE_APPLICATION_ID,
  "squareAccessToken": process.env.SQUARE_ACCESS_TOKEN
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here's the Glitch app:&lt;/p&gt;


&lt;div class="glitch-embed-wrap"&gt;
  &lt;iframe src="https://glitch.com/embed/#!/embed/orderahead?path=index.html" alt="orderahead on glitch"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  The Deployed Demo Site
&lt;/h2&gt;

&lt;p&gt;You can experiment with this and even place test orders using the &lt;a href="https://developer.squareup.com/docs/orders-api/quick-start/step-4"&gt;demo credit card&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Play with the live demo: &lt;a href="https://orderahead.glitch.me/"&gt;https://orderahead.glitch.me/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, if you're new to Square, &lt;a href="//squareup.com/i/EATSWADESH"&gt;here's an invite&lt;/a&gt; to get free processing on up to $1,000 in credit card transactions for the first 180 days.&lt;/p&gt;

</description>
      <category>express</category>
      <category>square</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Day 2: hover, underline, list-disc, and px-*</title>
      <dc:creator>Daniel Feldroy</dc:creator>
      <pubDate>Sat, 18 Apr 2020 23:38:36 +0000</pubDate>
      <link>https://dev.to/feldroy/day-2-hover-underline-list-disc-and-px-3apn</link>
      <guid>https://dev.to/feldroy/day-2-hover-underline-list-disc-and-px-3apn</guid>
      <description>&lt;p&gt;I like it when links hovered over are underlined. I learned how to do this in Tailwind CSS today by adding &lt;code&gt;hover:underline&lt;/code&gt; to &lt;code&gt;a&lt;/code&gt; tags. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:underline"&lt;/span&gt;
  &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/feldroy/day-2-hover-underline-list-disc-and-px-3apn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Day 2: hover, underline, list-disc, and px-*
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On my Glitch project, I'm organizing links to my dev.to posts like the one you're reading by putting them in an unordered list. To my surprise, using this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Item 2&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gave me this result:&lt;/p&gt;

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

&lt;p&gt;That almost works. I like my unordered lists to have bullets. The docs told me to use &lt;code&gt;list-disc&lt;/code&gt; in a class on the &lt;code&gt;ul&lt;/code&gt; element, so I did. And I got:&lt;/p&gt;

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

&lt;p&gt;Hmmm... the bullets appear but they are at the edge of the containing &lt;code&gt;div&lt;/code&gt;. Then I remembered that Tailwind CSS makes it easy to adjust horizontal padding through the use of the &lt;code&gt;px-*&lt;/code&gt; classes. After a little experimentation, I settled on &lt;code&gt;px-6&lt;/code&gt;. This is how it looks now:  &lt;/p&gt;

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

&lt;p&gt;And the code for the list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-disc px-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Item 2&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally I put in my content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list-disc px-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; 
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:underline"&lt;/span&gt; 
      &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/feldroy/day-1-building-a-page-after-a-css-reset-1dif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Day 1: Building a Page After a CSS Reset
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:underline"&lt;/span&gt; 
       &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://dev.to/feldroy/day-2-hover-underline-list-disc-and-px-3apn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         Day 2: hover, underline, list-disc, and px-*
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is &lt;a href="https://glitch.com/~tailwindpractice-day-02"&gt;today's code on glitch&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>todayilearned</category>
      <category>100daysofcode</category>
      <category>html</category>
    </item>
  </channel>
</rss>
