<?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: Jacob Colborn</title>
    <description>The latest articles on DEV Community by Jacob Colborn (@jakesweb).</description>
    <link>https://dev.to/jakesweb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F105609%2F25c74106-426a-46d9-a5c2-4cca0a23a041.jpeg</url>
      <title>DEV Community: Jacob Colborn</title>
      <link>https://dev.to/jakesweb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jakesweb"/>
    <language>en</language>
    <item>
      <title>Freelance Work - Will it be Right for Me</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Wed, 01 Jul 2020 02:46:49 +0000</pubDate>
      <link>https://dev.to/jakesweb/freelance-work-will-it-be-right-for-me-595a</link>
      <guid>https://dev.to/jakesweb/freelance-work-will-it-be-right-for-me-595a</guid>
      <description>&lt;p&gt;&lt;a href="https://i.giphy.com/media/bPTXcJiIzzWz6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/bPTXcJiIzzWz6/giphy.gif" alt="No Idea Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have my workspace prepared, well mostly. My desk is cleaned off. I have a clean notebook for notes. I created a new Joplin notebook to take long term notes. I created a directory in Google Drive for the documents I'll need. I think I am ready to finally start freelancing.&lt;/p&gt;

&lt;p&gt;There is no telling if this is the right move for me. I will be using this as an opportunity to create some experience and build a decent portfolio/resume for when I start looking for company positions later in my career. Since I am just starting, this will be moonlight work while I maintain my current day job. I hope I can find the right balance between working and family, now that I am adding even more hours, but I was always taught that if you had a dream you had to reach out for it. I hope that I can find that balance.&lt;/p&gt;

&lt;p&gt;I just picked up my first client, so I am nervous. I am writing this mainly as a starting point to be able to look back. Maybe I can encourage myself later when it gets hard and I can think back to how idealistic I was. I am dedicated to getting this first project right. I am secure in knowing that I have support from multiple places that can help me if I get in trouble. Let this be log number 1 on my first day as a freelancer.&lt;/p&gt;

&lt;p&gt;Thanks for reading, I hope this wasn't rambling or incoherent. &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Deploying to Netlify with Gridsome</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Mon, 22 Jun 2020 03:09:26 +0000</pubDate>
      <link>https://dev.to/jakesweb/deploying-to-netlify-with-gridsome-me4</link>
      <guid>https://dev.to/jakesweb/deploying-to-netlify-with-gridsome-me4</guid>
      <description>&lt;p&gt;Netlify is a superbly easy way to host statically generated websites. I am currently hosting my "portfolio" on Netlify (in quotes because it is a work in progress that I am not really ecstatic about). Gatsby is very easy to deploy on Netlify. Netlify will pickup the Gatsby site from Github (or Gitlab or Bitbucket) and automatically fill in the build command and publishing directory. Netlify will operate the same way with any static site generator, but does not necessarily automatically recognize them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oEhCDLWr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3uelyb8tx1uxnb4w59rl.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oEhCDLWr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3uelyb8tx1uxnb4w59rl.PNG" alt="Netlify Deployment Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you create a new site in Netflify, you are first asked to point it to your repository. For me, my repository was hosted on Github. Since I have my Netlify already authorized to read my Github, I just selected my project's repository from the list. I do have security enabled and only allow Netlify to read repositories I approved, so I did have to first allow it to read that repo from my Github authorized application settings. After that, you need to tell Netlify how to build and what to display. In order to build the Gridsome site, the build command is &lt;code&gt;gridsome build&lt;/code&gt; and the directory that is produced to publish is &lt;code&gt;dist&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This is a very simple article, but I found myself not knowing quite how to deploy Gridsome since I just dove right in and did not read all of the documentation. Gatsby is a little simpler since Netlify will automatically populate the build command and published directory, but does not do this with Gridsome in my experience. I do recommend Netlify since it is so easy to get up and running. They also offer excellent add-ons for your sites like the ability gather form data and host "serverless" functions right from the Netlify deployment. &lt;/p&gt;

</description>
      <category>gridsome</category>
      <category>netlify</category>
    </item>
    <item>
      <title>Incinicreator</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Sat, 06 Jun 2020 02:41:10 +0000</pubDate>
      <link>https://dev.to/jakesweb/incinicreator-2o5k</link>
      <guid>https://dev.to/jakesweb/incinicreator-2o5k</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I attempted to build a website creation utility that allowed the users to control the web monetization of the content they would deliver. This would tie in to a web monetization wallet that they specified with no interaction from us as a host. Read below under the additional info to see why I think this project largely was a failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Creative Catalyst&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jakesweb" rel="noopener noreferrer"&gt;
        jakesweb
      &lt;/a&gt; / &lt;a href="https://github.com/jakesweb/incinicreator" rel="noopener noreferrer"&gt;
        incinicreator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      an open source platform for creators to share their work while getting monetized
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Incinicreator&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Where creative works can generate money&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;The hope of this project is to allow users to create, manage, and host web sites that allow them to expose their talent in exchange for simple monetization.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How Web Monetization Works&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;The platform will extensively use the web monetization standard to allow for payments. The standard utilizes micro-payments which can be used to unlock content. More about web monetization can be found at the &lt;a href="https://webmonetization.org/" rel="nofollow noopener noreferrer"&gt;web monetization web page&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;The project is a work in progress and as I create more documentation this page will be updated. For now the stack will be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;MongoDB (accessed through Mongoose)&lt;/li&gt;
&lt;li&gt;Auth0 (for authentication)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jakesweb/incinicreator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;I used this as a platform to start working with Vue. I created the front-end with Vue.js and was very happy with the choice. The syntax and component/view development of Vue work for me very well. I look forward to working on some other projects with this technology. The other aspects of the project were familiar to me using Node and Express.&lt;/p&gt;

&lt;p&gt;Two of the largest technical challenges faced during development was how to upload and later reference content and how to generate a web server to host the websites.&lt;/p&gt;

&lt;p&gt;The content was first being handled as data being uploaded to an Amazon S3 bucket. The SDK provided by Amazon was easy to get up and running. I later changed to having Sanity.Io handle the content for an easier reference division for each creator. This proved to be untenable because Sanity did not immediately present an API to handle video.&lt;/p&gt;

&lt;p&gt;To set up the webserver, I looked into creating bash scripts to handle text changes to Nginx configuration files. This worked as expected and Node provided an easy way to handle the system interaction to run the scripts. I created a new configuration file for each site, which would make it easier to remove the websites if the creator ever wanted to remove their work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources/Info
&lt;/h2&gt;

&lt;p&gt;This project was a failure. I am submitting this since I did drop some hours into it and there is a good framework to expand upon if I ever figure out some of the hurdles I ran into. I am using this as a post-mortem for this project. &lt;/p&gt;

&lt;p&gt;The first thing that I failed on (and I think a lot of projects suffer from this) is scope. I scoped a very large project. One that would have been hard to accomplish with six months and tried to cram it into one. The biggest problem was not recognizing this until it was much too late. By the time I realized that generating a web site and allowing it to be edited was a large undertaking, it was only 1 week until the deadline. There was no way I could pivot or reduce the scope.&lt;/p&gt;

&lt;p&gt;I attempted to preserve but my attitude became soured. It was hard to sit down and focus while already feeling defeated. This brings us to the second failure, cynicism. Feeling defeated already, I made it that much harder to move forward. You can sometimes be your own worst enemy.&lt;/p&gt;

&lt;p&gt;I can sit here and make excuses for why I was unable to complete my intended project, but in reality, it came down to my own project management. Having a clearly defined plan would have paid off in the execution. I could have salvaged some part of this. I could have created a completed project rather than a broken, incoherent mess. I am fortunate to be able to look back on this and learn. Project management should entail a larger part of the task. &lt;/p&gt;

&lt;p&gt;Thank you for reading. Look for a future update and, you never know, I may figure out some of the technical challenges I had and finish this.&lt;/p&gt;

</description>
      <category>gftwhackathon</category>
    </item>
    <item>
      <title>Web Monetization for Creatives Update</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Sun, 17 May 2020 00:33:57 +0000</pubDate>
      <link>https://dev.to/jakesweb/web-monetization-for-creatives-update-2cao</link>
      <guid>https://dev.to/jakesweb/web-monetization-for-creatives-update-2cao</guid>
      <description>&lt;p&gt;I believe this is pretty close to the halfway point of the hackathon now, so I wanted to provide an update. You can find the project at &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWogaON8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-28d89282e0daa1e2496205e2f218a44c755b0dd6536bbadf5ed5a44a7ca54716.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jakesweb"&gt;
        jakesweb
      &lt;/a&gt; / &lt;a href="https://github.com/jakesweb/incinicreator"&gt;
        incinicreator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      an open source platform for creators to share their work while getting monetized
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Incinicreator&lt;/h1&gt;
&lt;h2&gt;
Where creative works can generate money&lt;/h2&gt;

&lt;p&gt;The hope of this project is to allow users to create, manage, and host web sites that allow them to expose their talent in exchange for simple monetization.&lt;/p&gt;
&lt;h2&gt;
How Web Monetization Works&lt;/h2&gt;

&lt;p&gt;The platform will extensively use the web monetization standard to allow for payments. The standard utilizes micro-payments which can be used to unlock content. More about web monetization can be found at the &lt;a href="https://webmonetization.org/" rel="nofollow"&gt;web monetization web page&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
Stack&lt;/h2&gt;
&lt;p&gt;The project is a work in progress and as I create more documentation this page will be updated. For now the stack will be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;MongoDB (accessed through Mongoose)&lt;/li&gt;
&lt;li&gt;Auth0 (for authentication)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jakesweb/incinicreator"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
.

&lt;p&gt;During the first part of the creation of the application, which I have foolishly called Incinicreator, I have kept a good pace to be able to finish by the end of the hackathon. This may seem trivial, but one of the number one things that can go wrong on a project is scoping and/or pacing making it impossible to finish by the deadline. My initial idea is still intact, but some of the implementation details are starting to shift.&lt;/p&gt;

&lt;p&gt;First of all, the stack has been confirmed as Node.js with Express for the server and MongoDB for datastore. Authentication is being provided from Auth0. Front end deployment is being handled by Vue.js. I was nervous with the Vue.js at the start since I have never used it before, but I wanted this hackathon to be a way for me to learn a new skill (along with the knowledge of web monetization platform). Google Cloud Platform is where I am currently working to store user data. Over the last 2 days, I have been researching how to get the data stored and protected.&lt;/p&gt;

&lt;p&gt;So far I have been happy with Vue.js. The learning process isn't very complicated and the way views and components are built seems to be intuitive. I have enjoyed building the pages out for my application so far. Also, the Auth0 authorization script makes the route protection simple.&lt;/p&gt;

&lt;p&gt;I am starting on the back stretches now. I am working on the user interaction for uploads and beginning testing of that. After that, I will just need to build up template sites for creative users to select from and, finally, to finish the help page to assist with getting wallets setup. I believe this should be able to be completed by the end of the coming week, allowing me plenty of time for testing and security assurance. With enough time, in the end, I hope to have a user dashboard where they can see page hits, monetization stats, which works are the most popular, etc. &lt;/p&gt;

</description>
      <category>gftwhackathon</category>
    </item>
    <item>
      <title>Web Monetization for Creatives</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Mon, 11 May 2020 04:05:30 +0000</pubDate>
      <link>https://dev.to/jakesweb/web-monetization-for-creatives-4lfe</link>
      <guid>https://dev.to/jakesweb/web-monetization-for-creatives-4lfe</guid>
      <description>&lt;p&gt;My initial thought was how to get web monetization directly into the hands of the creative community? Sure, Mozilla had started working on this with VR developers, but it was better suited to developers. How do we get writers, artists, and videographers to monetize their work with no coding?&lt;/p&gt;

&lt;p&gt;I believe the solution is a site generator/management tool that allows them to utilize their own WM wallet to collect micro-payments from their audiences directly. The signup/initial site creation process would require the user to set up or supply wallet information. The provided page templates would suggest what could be premium content to utilize the WM features. &lt;/p&gt;

&lt;p&gt;This should be a learning experience for me. I am starting the project by learning a new framework (Vue.js) to assist with development. The server will do most of the hard work, though, hosting the various web sites and uploads. I will have to pay special attention to how that traffic is routed and secured. I am beginning by setting up most of the front-end. I do worry this is a bigger project than can be pulled together in under a month, but I am hopeful. Even if I cannot finish it by June 5th, who knows, it could grow further?&lt;/p&gt;

&lt;p&gt;Let me know if you have any thoughts or suggestions below. I am looking forward to building this application. If you would like to checkout the progress, please check the code out at &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWogaON8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-28d89282e0daa1e2496205e2f218a44c755b0dd6536bbadf5ed5a44a7ca54716.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jakesweb"&gt;
        jakesweb
      &lt;/a&gt; / &lt;a href="https://github.com/jakesweb/incinicreator"&gt;
        incinicreator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      an open source platform for creators to share their work while getting monetized
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Incinicreator&lt;/h1&gt;
&lt;h2&gt;
Where creative works can generate money&lt;/h2&gt;

&lt;p&gt;The hope of this project is to allow users to create, manage, and host web sites that allow them to expose their talent in exchange for simple monetization.&lt;/p&gt;
&lt;h2&gt;
How Web Monetization Works&lt;/h2&gt;

&lt;p&gt;The platform will extensively use the web monetization standard to allow for payments. The standard utilizes micro-payments which can be used to unlock content. More about web monetization can be found at the &lt;a href="https://webmonetization.org/" rel="nofollow"&gt;web monetization web page&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
Stack&lt;/h2&gt;
&lt;p&gt;The project is a work in progress and as I create more documentation this page will be updated. For now the stack will be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;MongoDB (accessed through Mongoose)&lt;/li&gt;
&lt;li&gt;Auth0 (for authentication)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jakesweb/incinicreator"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
.

</description>
      <category>gftwhackathon</category>
    </item>
    <item>
      <title>ClickConnect</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Sat, 04 Apr 2020 18:45:52 +0000</pubDate>
      <link>https://dev.to/jakesweb/clickconnect-1kg6</link>
      <guid>https://dev.to/jakesweb/clickconnect-1kg6</guid>
      <description>&lt;h2&gt;
  
  
  My Idea
&lt;/h2&gt;

&lt;p&gt;Having been limited to Zoom and Webex meetings for the last 3 weeks, I have seen some of the issues with collaboration software as it sits now for some tasks. Screen share can be bulky. Application share is limited to a single application. My plan is to utilize a borderless real-time collaboration through the Twilio Video API. I hope to create a platform that will allow for individual applications to be delivered and viewed just likely they were to be used natively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Still early in the development process (I am going to working on sketches today), I believe the stack will simply be utilizing React with Twilio Serverless services (when in Rome, I suppose). I still need to figure out pricing and ensuring this is economical for a solution, but an initial price estimate should have no problem with running this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;A big question with any real-time communication is security. The first part of the security plan is to utilize the Twilio Authy service to set up 2FA, which will be a requirement for users. The Twilio API already includes encryption for the endpoints, so nothing to worry about there. Past that, I will be working on a list of good to have user options that increase security by default and design considerations that would offer the most secure experience possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;I will be doing all of the work from &lt;a href="https://github.com/jakesweb/clickconnect"&gt;https://github.com/jakesweb/clickconnect&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know if anyone has any thoughts or opinions on this, or just wish me luck down in the comments. This is my first hackathon, so it will be new to me building with a deadline and goals (good experience to have though). I can't wait to see what everyone else is going to make!&lt;/p&gt;

</description>
      <category>twiliohackathon</category>
    </item>
    <item>
      <title>User Authorization with Next.js and Apollo</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Sun, 19 Jan 2020 20:08:43 +0000</pubDate>
      <link>https://dev.to/jakesweb/user-authorization-with-next-js-and-apollo-1fan</link>
      <guid>https://dev.to/jakesweb/user-authorization-with-next-js-and-apollo-1fan</guid>
      <description>&lt;h2&gt;
  
  
  What Happened
&lt;/h2&gt;

&lt;p&gt;I have been working on an esports news submission web application for the last 2 months now (with a hearty break during December, so maybe closer to a month). Recently, I completed the article submission component. I mounted this component through a submit article page on the site. After getting the functionality running I wanted to make it so only users could submit an article. And, rather than having them write out the article to only be denied, I thought "why not let them know upfront you have to be logged in to submit an article?"&lt;/p&gt;

&lt;p&gt;I started working through this process. My initial idea was to run a current user query within the component to get access to the current user's id. If this didn't return any data then I would know that the user was not logged in. After writing this up I could not find a way to encapsulate the submission Mutation within a user Query. After trying a few different methods everyone returned errors. Taking a step back I saw a solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;Taking that step back I saw a solution on the Next.js page that is used to mount the article submission component. By utilizing the &lt;code&gt;&amp;lt;User&amp;gt;&lt;/code&gt; component, I could wrap the &lt;code&gt;&amp;lt;Submit&amp;gt;&lt;/code&gt; component within the &lt;code&gt;&amp;lt;User&amp;gt;&lt;/code&gt; component's returned data. For further clarity, here is the full &lt;code&gt;&amp;lt;User&amp;gt;&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-apollo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gql&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;graphql-tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&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;prop-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CURRENT_USER_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    me {
      id
      email
      name
      permissions
    }
  }
`&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;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;CURRENT_USER_QUERY&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;payload&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Query&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CURRENT_USER_QUERY&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

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



&lt;p&gt;So, if we take that &lt;code&gt;payload&lt;/code&gt; returned from the component we can pass this to the &lt;code&gt;&amp;lt;Submit&amp;gt;&lt;/code&gt; component via a prop. Taking this approach we can change our &lt;code&gt;submit.js&lt;/code&gt; page from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Submit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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



&lt;p&gt;To something that will gather data from the &lt;code&gt;&amp;lt;User&amp;gt;&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-apollo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Submit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/User&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Signin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/Signin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt; &lt;span class="nx"&gt;isLoggedIn&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&amp;gt;}&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The payload here is then passed to &lt;code&gt;&amp;lt;Submit&amp;gt;&lt;/code&gt; within the &lt;code&gt;isLoggedIn&lt;/code&gt; prop. Taking that prop, we can use some if/else statements to either render the submission form or render a login page, depending on what the current user status is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="nx"&gt;Submission&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, if &lt;code&gt;isLoggedIn.me&lt;/code&gt; exists, then the user is logged in. The &lt;code&gt;me&lt;/code&gt; part of this comes from the CURRENT_USER_QUERY. The query returns &lt;code&gt;id, email, name, permission&lt;/code&gt;. We could use any one of these, including &lt;code&gt;isLoggedIn.me.permission&lt;/code&gt; to make sure they are part of a group authorized to access this, but within the web application, any logged-in user is allowed to submit an article. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Conclusion
&lt;/h2&gt;

&lt;p&gt;This strategy could be utilized for any level of authorization. If this was an admin form I could take the returned data and look for the permission part of the object (this is defined in the query from &lt;code&gt;&amp;lt;User&amp;gt;&lt;/code&gt; and stored in the database for each user). This particular time, I only look for any data at all. As long as that data exists, the user is logged in. This is another excellent lesson in always taking a step back in what we are doing. I spent longer on this then I should but it was because I tried so many different iterations of how I thought it was supposed to work, rather than taking a few minutes to review my thought process and take a different approach.&lt;/p&gt;

&lt;p&gt;Thank you for reading. As always, feel free to leave any comments about the code, my thought process, what I could be doing better, or just saying hey.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>apollo</category>
      <category>react</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Using React Hooks With Apollo</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Fri, 10 Jan 2020 04:25:54 +0000</pubDate>
      <link>https://dev.to/jakesweb/using-react-hooks-with-apollo-475j</link>
      <guid>https://dev.to/jakesweb/using-react-hooks-with-apollo-475j</guid>
      <description>&lt;h2&gt;
  
  
  My Setup
&lt;/h2&gt;

&lt;p&gt;I am using React with Apollo to connect to a GraphQL API utilizing Nextjs to handle the rendering and routing.  This means I have my Apollo client registered under &lt;code&gt;_app.js&lt;/code&gt; for Nextjs. The application I am building is an article submission website, similar to Dev.to, but for esports commentary and news. The package being used is the react-apollo package that has a react-hooks dependency for us to exploit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Am Writing This
&lt;/h2&gt;

&lt;p&gt;Everyone may be thinking this is a basic thing, and that's what I thought too. I was trying to find the best way to build out a Signout component. I didn't want to create a whole page for Signout, so I set it up as an Apollo Link that has an anchor tag embedded. On the anchor, there is an onClick handler that calls my useSignout hook. Getting it working as a Link and anchor I was able to style it like the rest of my navigation bar so I could just add it as an option once the user is logged in. The useSignout hook I created utilizes the useMutation hook from the react-hooks package. The code kinda speaks for itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@apollo/react-hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gql&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;graphql-tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&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;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SIGNOUT_MUTATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  mutation SIGNOUT_MUTATION {
    signout {
      message
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Signout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;useSignout&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SIGNOUT_MUTATION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onCompleted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
        &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;useSignout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Signout&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You notice that it still has all the normal flow of a React hook and Apollo mutation. So I created this and went running my Apollo application and what do you know ... an error. After searching for about a half-hour I finally found the answer, using a hook requires Apollo to know there is a hook coming. Now, I will preface the rest of this by saying that this was my first attempt at using hooks. Maybe if I had known how React hooks were supposed to function, this would have been a non-issue, but here we are. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Reason to Use a Hook Here
&lt;/h2&gt;

&lt;p&gt;The reason that I wanted to use a hook is that I didn't want to wrap my whole &lt;code&gt;&amp;lt;Link&amp;gt;&amp;lt;a&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;Link&amp;gt;&lt;/code&gt; flow in a weird kind of form. That wouldn't even work, was my first thought, but looking back (hindsight is the keyword for the year 2020 I believe) I can think of a way to put that in, but why not try out a hook for the first time? Also, this matched with the rest of my navigation (where I put the signout link) so the styling was consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Most people more familiar with Apollo and hooks will have seen this coming, but for us who are going on the first foray with hooks and Apollo, quickly learn we need to wrap our application in an Apollo Provider component from the react-hooks package in &lt;code&gt;react-apollo&lt;/code&gt;. Originally my code looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;myApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ApolloProvider&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Page&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ApolloProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Quickly, I found the issue. &lt;code&gt;&amp;lt;ApolloProvider&amp;gt;&lt;/code&gt; could not handle a hook by itself. This component could grab all of the other Apollo 'stuff' coming from our application, but this didn't fit with the rules for using hooks. If you are curious about what the full rules are, check out the &lt;a href="https://reactjs.org/docs/hooks-rules.html"&gt;Rules of Hooks&lt;/a&gt; from the ReactJS documentation. I didn't full deconstruct what rule this broke but I believe it is because the Apollo Hooks Provider is a React function component where the Apollo Provider component is a container component (I want to point out this could be very wrong, being my first React hook, feel free to let me know if that is way out of left field). After finding the react-hooks dependency on &lt;code&gt;react-apollo&lt;/code&gt; I found the solution. First I had to import the Apollo hook provider. I created a new &lt;code&gt;ApolloProvider&lt;/code&gt; with the react-hooks package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloProvider&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ApolloProviderHooks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@apollo/react-hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see from above, it is just another &lt;code&gt;ApolloProvider&lt;/code&gt; but this is being instantiated from the &lt;code&gt;react-hooks&lt;/code&gt; package inside of the &lt;code&gt;react-apollo&lt;/code&gt; package. Now I just take my same code as before and wrap the &lt;code&gt;Page&lt;/code&gt; component above the &lt;code&gt;ApolloProviderHooks&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;myApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ApolloProvider&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ApolloProviderHooks&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;apollo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
           &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;         &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Page&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;       &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ApolloProviderHooks&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ApolloProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The main learning experience here is if I am going to dive into some new technology, I should probably do more than just think, "Hey, I've heard of hooks, I think this is my solution." Here comes hindsight once again, read a document before trying it out. Like I said earlier, this was just me getting my feet wet with React hooks. I could have built it the same way as I built all my other Mutations, but I grew from this experience. If anyone has any easier ways to handle this, let me know. This is all for learning so the more I (we) all know the better. Have a great day and thanks for the read!&lt;/p&gt;

</description>
      <category>react</category>
      <category>apollo</category>
      <category>hooks</category>
    </item>
    <item>
      <title>2020 and Beyond</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Wed, 01 Jan 2020 22:53:52 +0000</pubDate>
      <link>https://dev.to/jakesweb/2020-and-beyond-3agh</link>
      <guid>https://dev.to/jakesweb/2020-and-beyond-3agh</guid>
      <description>&lt;h2&gt;
  
  
  New Year's
&lt;/h2&gt;

&lt;p&gt;It's a time for reflection. Part of reflecting is looking where you want to go since you have to assess where you are coming from in order to obtain where you are going. This means most blogging and social media are being flooded with resolutions and introspection. Here lies a record, for me only really, that I want to use as a guide for 2020 and even further if it is still applicable. If a read other than myself gets anything out of it, that will be a bonus for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 2019 Was For Me
&lt;/h2&gt;

&lt;p&gt;This year was for me more transformative than any year. I was able to reaffirm my faith. I was also able to see that my current job was demanding too much time away from things like family and faith. In the last 3 months of the year, I decided that my 2020 dedication would be to find a job with a better work-life balance while still being able to provide for my family and moving into my chosen career field, development. I started and stopped doing regular programming and blogging throughout 2019 and you can see that in my past articles, but I want to dedicate the first 3 months of 2020 to have a more consistent schedule.&lt;/p&gt;

&lt;p&gt;Now, with the meager time I was able to commit to web development, I learned 2 new skills that I want to strengthen into the new year. I built my portfolio website using Gatsby and fell in love with the quick deployment/build cycle. I am using Netlify to host it and there was nothing to learn there, just plug in your git repo and off you go. I was able to tie it to my personal domain and get SSL running on it through Netlify as well. Hands down the easiest experience of 2019. I also started learning Apollo and GraphQL using the &lt;a href="https://advancedreact.com/"&gt;Advanced React course from Wes Bos&lt;/a&gt;. I am not affiliated with Wes Bos in any way, but I want to mention it since it was an excellent course for learning.&lt;/p&gt;

&lt;p&gt;Personally, everything has started to look up. My wife has been going through treatments for a health issue and she has made such amazing progress and feels so much better. We are starting to work on what I consider the hardest part of being married, finances. Working out how to save, what to save, and, more importantly, what to spend on has been a struggle for us over the last 3 months but is essential when I am starting to look for new work. I have also started reading again thanks to an investment made to a Kindle for a Christmas gift. I never fell out of love with reading but the stress of life forced me to think it was such an unimportant thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2020 Goals and Beyond
&lt;/h2&gt;

&lt;p&gt;I look forward to two major things this year, becoming better disciplined with development and finding my first job as a developer. I have already started to see what is available to me for my career inception. Hopefully, I can find something that will allow the transition between careers to be a lot less stressful than I am currently stressing about. I will be looking for work in my area but I think most of the places I want to work would require me to work remotely or relocate; having an open mind during this process will be essential.&lt;/p&gt;

&lt;p&gt;I want to complete my first full scall React/Apollo/GraphQL application before March of this year. I have the framework done and I am getting all of the logic completed now. There will be a blog post to follow this about working with React hooks in Apollo since I just picked that up last night (Happy New Year to me indeed!). &lt;/p&gt;

&lt;p&gt;These are my reflections. What about you? It seems silly that humans picked an arbitrary time of every year to reflect on their lives, but it is an essential part of being a well-rounded human being. Happy New Year to everyone reading this and I wish you success with whatever you have decided was important to you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Gatsby GraphQL Imports from JSON</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Sat, 30 Nov 2019 02:40:58 +0000</pubDate>
      <link>https://dev.to/jakesweb/gatsby-graphql-imports-from-json-k2g</link>
      <guid>https://dev.to/jakesweb/gatsby-graphql-imports-from-json-k2g</guid>
      <description>&lt;p&gt;To see the full code you can check it out on my Github &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jakesweb"&gt;
        jakesweb
      &lt;/a&gt; / &lt;a href="https://github.com/jakesweb/portfolio"&gt;
        portfolio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      My portfolio website. Created with Gatsby. Deployed with Netlify.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I was working on building my portfolio site. Besides realizing that I do not have nearly enough projects to make a legitimate portfolio site, I also realized that I wanted to be able to add projects to a grid to make a clean layout. Now, I could have just created a Component with all of the individual projects copied and pasted, but I just needed some key data to change per grid item. This sounds like a job for queries! I didn't want a whole database and since it is structured data, that sounded like a job for json!&lt;/p&gt;

&lt;p&gt;Gatsby comes with GraphQL builtin. GraphQL is a query language. It can read in from databases, but it can also read from other structured data if loaded correctly. Let's take a look at that first. &lt;/p&gt;

&lt;p&gt;To load the data for GraphQL we have to let Gatsby know how to push it over. This was added to my &lt;code&gt;gatsby-config.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="s2"&gt;`gatsby-transformer-json`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-filesystem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`json`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;path&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;__dirname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/src/json`&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;You will need the &lt;code&gt;gatsby-transformer-json&lt;/code&gt; NPM package to utilize this. The path is where I stored the json file, inside &lt;code&gt;src/json&lt;/code&gt; which I created. The configuration file is what tells Gatsby how to load the file into the parser and allow it to be queried by GraphQL. The json file was just a list of 3 attributes that all of my Project components would need. I named the json file &lt;code&gt;projects.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "image": "https://res.cloudinary.com/jakes-web/image/upload/e_outline/v1574999653/portofolio/Pomodoro.png",
    "link": "https://codepen.io/jakesweb/live/awLdxp",
    "title": "Pomodoro Clock"
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, you will want to know how to query this data. GraphQL picks up the file and loads the data in as &lt;code&gt;&amp;lt;Filename&amp;gt;Json&lt;/code&gt; so in my case it was &lt;code&gt;ProjectsJson&lt;/code&gt;. Being GraphQL it preloads a query for all data from the json named &lt;code&gt;allProjectsJson&lt;/code&gt;. This is what we can utilize to pull the data into our Gatsby component. You can see the GraphQL playground by starting your Gatsby development server and then browsing to &lt;a href="http://localhost:8000/___graphql"&gt;http://localhost:8000/___graphql&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are following along on the Github repository I linked at the top, I created a component to use for styling each project link. This is &lt;code&gt;src/components/ProjectItem.js&lt;/code&gt;. I then linked this component over to the &lt;code&gt;Project.js&lt;/code&gt; component. The Project component needs to have an import for GraphQL and StaticQuery as such: &lt;code&gt;import { StaticQuery, graphql } from "gatsby"&lt;/code&gt; to utilize GraphQL.&lt;/p&gt;

&lt;p&gt;From here I created a component to gather a list of Project Items into an array. Now, pausing for a moment of reflection, I could probably do this without a helper function and just run straight into a &lt;code&gt;map&lt;/code&gt; function. I will be working that out once I make my personal website look better. &lt;code&gt;StaticQuery&lt;/code&gt; is a component that allows us to query the data from GraphQL. This is where we gather the data and lay it out into the &lt;code&gt;getProjectsList&lt;/code&gt; helper function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;getProjectsList&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectsArray&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;allProjectsJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;projectsArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProjectItem&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="nb"&gt;Array&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;Project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HeaderDiv&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;header-div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StaticQuery&lt;/span&gt;
      &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
        query ProjectItemQuery {
          allProjectsJson {
            edges {
              node {
                image
                link
                title
              }
            }
          }
        }
      `&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProjectGrid&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;getProjectsList&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;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ProjectGrid&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/HeaderDiv&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I know what you are thinking. That is a lot of curled braces, but that's GraphQL for you. The GraphQL query runs a query I called &lt;code&gt;ProjectItemQuery&lt;/code&gt;, this runs against a builtin query that is created by GraphQL called &lt;code&gt;allProjectsJson&lt;/code&gt;. It is easier to see how the edges and nodes work if you look through the GraphQL local viewer from your Gatsby develop server (which can be found at &lt;a href="http://localhost:8000/___graphql"&gt;http://localhost:8000/___graphql&lt;/a&gt;, as long as your Gatsby server is using port 8000). From the query, we want to get the data nodes of image, link, and title. The query pushes all the returned information to a variable called data. Taking that, it's passed into the &lt;code&gt;getProjectsList&lt;/code&gt; function to lay out the array and render the page.&lt;/p&gt;

&lt;p&gt;If you want to see this in practice you can head over to my &lt;a href="https://www.jakesweb.me"&gt;website&lt;/a&gt;. Don't mind the view right now, I am working on getting better as a designer! If you have any thoughts you can let me know in the comments. Thank you for reading!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>gatsby</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How to handle inputs with React</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Mon, 31 Dec 2018 04:44:28 +0000</pubDate>
      <link>https://dev.to/jakesweb/how-to-handle-inputs-with-react-9bp</link>
      <guid>https://dev.to/jakesweb/how-to-handle-inputs-with-react-9bp</guid>
      <description>&lt;p&gt;When working on my latest demo application, I ran into a problem with React; I wanted to create form. The problem with this simple task is I didn't want any backend or API to handle the form, instead, I wanted it to work within React. I found a lot of things that were complex, but I think I created a system that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gathering the data
&lt;/h2&gt;

&lt;p&gt;The first thing I did was create the "form." To do this, I created a group of inputs within a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. The input would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input 
    class="rounded" 
    id="gametitle" type="text" 
    placeholder="Game Title" 
    onChange={this.props.onChange} 
    value="{this.props.gameTitle}"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The most important part of this is the &lt;code&gt;onChange&lt;/code&gt; and the &lt;code&gt;value&lt;/code&gt; properties. The value property will read the state that is being generated by &lt;code&gt;onChange&lt;/code&gt;. &lt;code&gt;onChange&lt;/code&gt; is a method passed into the React class with a prop called &lt;code&gt;onChange&lt;/code&gt;. These work together to create an input that can be used to gather the data and then cleared.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;onChange = event =&amp;gt; {
    switch (event.target.id) {
        case "gametitle":
            this.setState({ gameTitle: event.target.value });
            break;
        ...
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The method will collect the &lt;code&gt;event&lt;/code&gt; generated. It will then use the input's &lt;code&gt;id&lt;/code&gt; value to match the correct case. From here, it gathers the current value of the input with &lt;code&gt;event.target.value&lt;/code&gt; and sets the state to be that value. &lt;code&gt;gameTitle&lt;/code&gt; was defined in the constructor of the React class, along with the other bits of state, before being used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the data
&lt;/h2&gt;

&lt;p&gt;After gathering all 4 inputs, I then needed to collect the data and clear the inputs for the next round of data. For this, a button was in order. The final input was the button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
    class="rounded"
    id="enter"
    type="submit"
    text="Add"
    onClick={this.props.onSubmit}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The button is a bit different. It uses the &lt;code&gt;onClick&lt;/code&gt; value to watch for user interaction (in this case when the user clicks the button area). The method was passed into the class via a prop (as was onChange) called onSubmit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;onSubmit = event =&amp;gt; {
    if (
      this.state.gameTitle === undefined
    ) {
      alert("Error: undefined element");
    } else {
      if (this.state.games == null) {
        this.setState({
          games: [
            {
              gameTitle: this.state.gameTitle,
              date: this.state.date,
              digital: this.state.digital,
              platform: this.state.platform
            }
          ]
        });
      } else {
        this.setState({
          games: [
            ...this.state.games,
            {
              gameTitle: this.state.gameTitle,
              date: this.state.date,
              digital: this.state.digital,
              platform: this.state.platform
            }
          ]
        });
      }
    }

    this.setState({
      gameTitle: "",
      date: todayDate,
      digital: false,
      platform: ""
    });
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are a few things going on here, so I will start from the top. The first thing to do is to make sure that the user has entered all of the required data. To do this, I check the four input's state value to see if it is &lt;code&gt;null&lt;/code&gt;. From there, I need to see if the &lt;code&gt;games: []&lt;/code&gt; array already has a value in it. If there is no value, I enter the four input's values as the first object. When a previous value exists, I reset the state to be the current value of state and then add the data to the rear. The array is modified with the spread syntax, &lt;code&gt;games: [...this.state.games]&lt;/code&gt;, which references the entire array and allows the current state to be appended. This will keep the state immutable. The final part sets the state of the inputs back to blanks since the inputs are using the state as their value.&lt;/p&gt;

&lt;p&gt;You can see all of the code for this at &lt;a href="https://gitlab.com/jcolborn/games-list"&gt;GitLab&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>User Authentication with Express.js</title>
      <dc:creator>Jacob Colborn</dc:creator>
      <pubDate>Fri, 12 Oct 2018 04:16:20 +0000</pubDate>
      <link>https://dev.to/jakesweb/user-authentication-with-expressjs-44od</link>
      <guid>https://dev.to/jakesweb/user-authentication-with-expressjs-44od</guid>
      <description>&lt;p&gt;Part of making an Express.js based application is being able to authenticate users. The question after getting them authenticated is what to do with that? &lt;/p&gt;

&lt;p&gt;My current strategy is to use a client-side cookie that is encrypted with a secret hash. To create a session, I use both the &lt;code&gt;cookie-parser&lt;/code&gt; and &lt;code&gt;express-session&lt;/code&gt; modules. I link them to my application with &lt;code&gt;app.use&lt;/code&gt; in &lt;code&gt;app.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookieParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cookie-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookieParser&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;application_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resave&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;saveUninitialized&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using that setup we can create sessions with &lt;code&gt;req.session&lt;/code&gt;. With the login route on the user router, we can set the session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&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="c1"&gt;// login the user and return the user object&lt;/span&gt;
    &lt;span class="c1"&gt;// if the login is successful&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This sets the email and the role to the user session. I defined three roles so far: student, instructor, and admin. There are two ways that I use these roles right now. In the routes, I can run an if statement that renders a different page or passes a different property to the templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;studentpage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adminpage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unauthenticated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's not the most relevant example; you would typically check if the user is authenticated and then render a page if they are or redirect if they aren't. The other option is to take a middleware. In my middlewares directory I have &lt;code&gt;admin-auth.js&lt;/code&gt; which defines a middleware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then on the route that I want to check if there is an admin authentication with the middleware. The middleware will process before the route is allowed to continue processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../middlewares/auth-admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;authAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What this will do is pass the request to the middleware first. The middleware checks the role in the user session, and if the role is an admin role it allows the route to continue with &lt;code&gt;next()&lt;/code&gt;. The else path changes this to the unauthorized webpage if the user doesn't have a role or the role is not an admin role.&lt;/p&gt;

</description>
      <category>dev</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
