<?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: Jonathan Wang</title>
    <description>The latest articles on DEV Community by Jonathan Wang (@jwaang).</description>
    <link>https://dev.to/jwaang</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%2F119406%2F03f6ab9f-4ad2-448d-9807-f5435456892e.jpeg</url>
      <title>DEV Community: Jonathan Wang</title>
      <link>https://dev.to/jwaang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jwaang"/>
    <language>en</language>
    <item>
      <title>Side Project #3 - Decentrevent</title>
      <dc:creator>Jonathan Wang</dc:creator>
      <pubDate>Sat, 28 Aug 2021 22:59:32 +0000</pubDate>
      <link>https://dev.to/jwaang/side-project-3-decentrevent-b5a</link>
      <guid>https://dev.to/jwaang/side-project-3-decentrevent-b5a</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;A couple months back, I found out that you could build smart contracts off of the Ethereum blockchain and create decentralized applications to communicate with it. This was extremely surprising to me because I always viewed Ethereum strictly as a trading asset with no utility due to my lack of research. Once I read a little bit more about Ethereum, web3.js, and Solidity -- I knew I had to create my own dapp and explore this area a bit more.&lt;/p&gt;

&lt;p&gt;I wanted to create a dapp that could host events similar to Eventbrite. There would be two primary roles - Coordinator and Participant. The coordinator would be the whoever created the event and the participant would be anyone who purchased a ticket. The smart contract would hold the funds of participants and would only release the funds to the coordinator if the majority of participants voted the event as valid or if the voting period ends and there aren't enough votes. If the majority of participants voted the event as invalid or if the coordinator cancels the event before the start date, then the participants would be able to receive a refund. &lt;/p&gt;

&lt;p&gt;The reason why I implemented this feature is because coordinators can scam users and never end up hosting the event. This incentivizes coordinators to host legitimate events in order to receive payment. In addition, if the event is invalid, this will incentivize participants to vote the event as invalid in order to receive a refund. Lastly, if there are not enough votes and the voting period ends, the coordinator will be able to receive payment meaning there was not enough interest from participants to vote the event as invalid. This idea may sound interesting in theory but one caveat is that even if the coordinator hosts a legitimate event, a majority of participants can still band together and vote the event as invalid to trigger a refund. There might be more issues with this approach, but it doesn't matter because my main goal here was to learn more about web3.js and Solidity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📺 This isn't deployed anywhere but you can view the demo &lt;a href="https://streamable.com/q5mizn"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👨‍💻 Source Code &lt;a href="https://github.com/jwaang/decentrevent"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Solidity to create my smart contract&lt;/li&gt;
&lt;li&gt;web3.js to allow me to interact with the Ethereum blockchain&lt;/li&gt;
&lt;li&gt;IPFS to store my images, no database needed 😮&lt;/li&gt;
&lt;li&gt;Next.js on the front end as usual 😎&lt;/li&gt;
&lt;li&gt;Truffle suite's Ganache to deploy a local Ethereum blockchain on my personal workspace to develop. &lt;/li&gt;
&lt;li&gt;Tailwind CSS - This was my first time using this and I really liked it. I love the fact that it provides a wide variety for customization but sometimes it would get a bit too confusing when I had like 10+ classnames for an element. For a small project that doesn't require too much on the front end, I would probably use a different styling framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Development Process
&lt;/h3&gt;

&lt;p&gt;I first started by creating the smart contract on Remix IDE (great IDE btw). I personally like to think of a smart contract as the backend service deployed on the blockchain that handles all the business logic. Solidity is an interesting language and it reminded me of C++ so it wasn't too hard for me to pick up. There were some things that I had to get used to though, for example, you can't simply just call a method to get the length of an array. You have to declare a separate integer variable and keep track of the array size. Also it's extremely important to be as efficient with your code as possible. If not, you can significantly increase the cost of gas fees. The reason why this happens is because the smart contract uses gas for computation to modify storage variables on the smart contract. Solidity also has some cool data types like address which stores and Ethereum address and mapping which is a hashmap data structure. Function modifiers are also really cool - they serve as some form of prerequisite before the function can be called. Lastly, there isn't a date object built in for Solidity. To retrieve an approximate date time, you need to get the last mined block's timestamp. There's probably more stuff that I'm missing but these were the main things that I found interesting.&lt;/p&gt;

&lt;p&gt;Once I finished the smart contract, I began working on the front end portion by using Next.js, web3.js, and Metamask. Metamask is a Chrome extension that allows users to interact with dapps and web3.js is a Javascript library that allows users to create dapps. Basically, Metamask and web3.js serves as a bridge for communication between the Ethereum blockchain and the client side application.&lt;/p&gt;

&lt;p&gt;The dapp would contain only 3 pages:&lt;/p&gt;

&lt;h4&gt;
  
  
  Home page
&lt;/h4&gt;

&lt;p&gt;Displays all the events stored on the smart contract. The navbar would display the current account's address on the top right corner.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uqqrdcAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6436vn5mgi84t1z723xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uqqrdcAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6436vn5mgi84t1z723xg.png" alt="Home Page" width="879" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create page
&lt;/h4&gt;

&lt;p&gt;Allows any user to create an event. The create page would contain a form (shown below):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9oCp8j0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1z03i6qbr0nxe8egxz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9oCp8j0L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1z03i6qbr0nxe8egxz8.png" alt="Create Page form" width="880" height="770"&gt;&lt;/a&gt;&lt;br&gt;
I won't go over all the fields since some are pretty self explanatory.&lt;br&gt;
Cover Image&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coordinators can upload an image directly to IPFS to stylize their event. IPFS is a peer to peer network allowing users to store and share data (same thing as a torrent really) in a decentralized manner. This means that there isn't a centralized database required on my end to host these images. The user can simply upload an image, IPFS hashes the image, and our dapp stores the hash on the smart contract to reference when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Price (in Wei)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm using Ethereum's smallest denomination which is wei. 1000000000000000000 wei is equivalent to 1 Ether.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start Date Offset (in Seconds) / End Date Offset (in Seconds)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start date determines when the event will start and end date determins when the event will end.&lt;/li&gt;
&lt;li&gt;This is the number of seconds after creating the event. If a coordinator provides SD for Start Date Offset and ED for End Date Offset and assuming that our block's current timestamp of the event creation is T, the event's start date will be T + SD seconds and the end date will be T + ED seconds, where ED &amp;gt; SD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voting Period Offset (in Seconds)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voting period is the amount of time the participants are allowed to vote after the event has ended.&lt;/li&gt;
&lt;li&gt;If the coordinator provides a value of VP seconds for Voting Period, then users will only be allowed to vote on an event between T + ED and T + ED + VP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is this user friendly? Hell no lol, having the coordinator calculate the number of seconds to determine the start date, end date, and voting period would be a huge pain. Again the user interface and user experience was not a primary concern for me when I was working on this project.&lt;/p&gt;

&lt;h4&gt;
  
  
  Drilldown page
&lt;/h4&gt;

&lt;p&gt;Once a user clicks on an event on the home page, they will be redirected to the drilldown page allowing users to view the event with more information.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mnRf9DJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vk10e0pyki5a5o9313wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mnRf9DJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vk10e0pyki5a5o9313wu.png" alt="Drilldown" width="751" height="875"&gt;&lt;/a&gt;&lt;br&gt;
Depending on the user's role and status of the event, different actions and messages will be presented on the page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Non coordinators or non participants can purchase a ticket only if the event is not running or not canceled.&lt;/li&gt;
&lt;li&gt;Only participants can receive a refund if the event is canceled or voted as invalid by the majority.&lt;/li&gt;
&lt;li&gt;Only participants can vote (Invalid or Valid) if the event is not canceled, has ended, is within the voting period, has bought a ticket already, and has not voted yet.&lt;/li&gt;
&lt;li&gt;Only the coordinator can retrieve payment if the event has not been canceled and enough voters have voted the event as valid OR the event has not been canceled and the voting period has ended and does not have majority vote.&lt;/li&gt;
&lt;li&gt;Only the coordinator can cancel the event if the event has not started yet and has not been canceled yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Potential Add Ons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instead of asking coordinators to provide Start Date, End Date, and Voting Period offset values in seconds; we can replace the input box with date pickers allowing a more user friendly approach.&lt;/li&gt;
&lt;li&gt;There should be a minimum amount of time required for voting period offset. The coordinator can currently set the Voting Period offset to 1 second and receive payment.&lt;/li&gt;
&lt;li&gt;Pagination on the home page instead of displaying all events stored on the smart contract.&lt;/li&gt;
&lt;li&gt;Filterable home page which displays events that have not started yet, have started, or have ended.&lt;/li&gt;
&lt;li&gt;Allowing coordinators to select which denomination they would like to pay in instead of defaulting to wei. &lt;/li&gt;
&lt;li&gt;Better styling lol&lt;/li&gt;
&lt;li&gt;...and more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is an extremely fun space to learn about and I'm excited to see what lies ahead for this technology.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jXMWJsZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media.giphy.com/media/cEYFeE4wJ6jdDVBiiIM/giphy-downsized-large.gif%3Fcid%3Decf05e47wha6a58a9vgacfv1ak9vmekwm39japh7z19nimlw%26rid%3Dgiphy-downsized-large.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jXMWJsZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media.giphy.com/media/cEYFeE4wJ6jdDVBiiIM/giphy-downsized-large.gif%3Fcid%3Decf05e47wha6a58a9vgacfv1ak9vmekwm39japh7z19nimlw%26rid%3Dgiphy-downsized-large.gif%26ct%3Dg" alt="space cowboy" width="490" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
      <category>smartcontract</category>
      <category>dapp</category>
    </item>
    <item>
      <title>Side Project #2 - Oyego</title>
      <dc:creator>Jonathan Wang</dc:creator>
      <pubDate>Sun, 01 Aug 2021 02:18:02 +0000</pubDate>
      <link>https://dev.to/jwaang/side-project-2-oyego-190n</link>
      <guid>https://dev.to/jwaang/side-project-2-oyego-190n</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;I really enjoy watching movies and then rating them using an app called &lt;a href="https://letterboxd.com/"&gt;Letterboxd&lt;/a&gt;. I then thought, "Well wouldn't it be cool if we could rate music as well?" And that's how Oyego was born - it's basically Letterboxd, but for music!&lt;/p&gt;

&lt;p&gt;You can check out Oyego &lt;a href="https://oyego.herokuapp.com/"&gt;here on Heroku&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Please note that you will be unable to log in if I have not personally reached out to you. This is because the application uses Spotify's API, and the app is currently in Development Mode, so we are limited to a max of 25 users that I have to add in manually. 😟&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to check out the demo video/source code, you can do so &lt;a href="https://github.com/jwaang/oyego"&gt;here on Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've watched the demo video, you're probably wondering if it was a good idea to list ALL of the most recent reviews on the home page, why the search page only returns only 10 results, or maybe something else. All of this was intentional, and I made these decisions to limit the scope of my project. This project was meant to be a proof of concept, so I didn't want to bombard myself with a huge list of features to add because I have more side projects that I want to work on. Who knows, maybe I'll pick this up another time to turn this into a more thought-out application with all the bells and whistles. 🤷‍♂️&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;p&gt;This project was my first time using NextJS, and I have to say that I like this framework a lot. There were many cool out-of-the-box features that I could use, like next/auth, next/img, next/router, and more, that helped me with my project. I also wanted to learn more about server-side rendering and see how it differed from client-side rendering.&lt;br&gt;
I also used GraphQL and Apollo Client/Server (also first time) to learn more about back-end design and programming and explore other backend technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Development Process
&lt;/h3&gt;

&lt;p&gt;The first step to any project is to design and plan everything out. But before doing so, I first had to explore Spotify's API because I wasn't sure if I could use it to search for items in their database (hint: you can 🥳). Once I had confirmed that this was possible, I then began creating mock-up designs. I started with Figma and drafted how I wanted my user interface to look. You can view a screenshot of my design below. Please note that I am not a Figma master; my thoughts are (literally) all over the place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H_LzDq2q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/a319e44ef8c90da25dbebff2e5d7311e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H_LzDq2q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/a319e44ef8c90da25dbebff2e5d7311e.png" alt="Figma"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once I had the user interface created and the workflow detailed, I could begin planning what queries or mutations I needed to create. I was aware that there could be an endless amount of features to add in, so I decided to limit my list of features and focus only on the key components. Here's the list of features that I came up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spotify authentication for login page&lt;/li&gt;
&lt;li&gt;Fetch all reviews in the database for the home page&lt;/li&gt;
&lt;li&gt;Fetch specific reviews in the database for the user profile page&lt;/li&gt;
&lt;li&gt;Search Spotify's database for albums (yes, only albums) for the search page&lt;/li&gt;
&lt;li&gt;Create reviews&lt;/li&gt;
&lt;li&gt;Update/Delete reviews, only if you're the user who created the review&lt;/li&gt;
&lt;li&gt;Style and animate everything, so it looks litty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I had everything planned out, I began developing. I created a NextJS project and learned about next-auth providers, making it extremely simple to set up a Spotify login. Once I setup authentication, I began setting up my first Spotify search query on GraphQL. Setting up the types and resolvers was straightforward, but I did come across my first issue. To hit a Spotify endpoint, you have to pass in an access token that can be used once the user is properly authenticated with Spotify. I know that this was possible with the context argument, but I couldn't figure out how to communicate between the client and server even after spending two days on the issue. As a result, I decided to pass in the access token as a parameter for the query itself, which isn't ideal 😢. After that, everything was smooth sailing from there (sort of)! I continued to work on my queries and mutations and would work on the front-end piece concurrently to make sure everything was connected and working properly. There was a time where I did spend an hour trying to figure out why my query wasn't working until I realized I was missing a curly brace in my gql statement... But besides that, I also learned about updating the cache in Apollo which I thought was very useful and important.&lt;/p&gt;

&lt;p&gt;Once I felt like the backend was complete, I could begin working on styling everything. I first added in the background waves I had created in Figma. It wasn't easy to get everything the way I wanted it to, but I eventually figured it out after many hours 😩. After that, I just started styling the hell out of EVERYTHING - the buttons, the cards (using the glassmorphism effect), the pages, the navbar, etc. I usually use prebuilt UI components, but I wanted to challenge myself and see if I could design something, and I gotta say I'm pretty proud of myself. I usually copy and paste flexbox code and hope that it works, but I actually sat down and decided to dive deeply into flexbox. During this time, I also cleaned up the code base and fixed some small bugs floating around. AND last but not least, I thought I needed animations on this application because everyone loves animations 😩🔥. I had heard about Framer Motion a couple of weeks prior and decided to give it a try. All the sick-ass animations you see on the application were 100% accomplished with Framer Motion, and I'm super happy with how it turned out. It was effortless to set up and learn, and I feel like I just scratched the surface with what I know. I will definitely be using this again!&lt;/p&gt;

&lt;p&gt;The last issue that I faced was with next/img. What's really cool about next/img is that it optimizes the image on the server by lazy loading it in the application for faster load times. One caveat (or maybe not, idk) is that you have to configure the hostname of the image url before doing so. So if your hostname is static, then it's all good! But if it's dynamic, well... In my application, every time a users creates a review, it would save the url of the user's profile picture in the database. Spotify, unfortunately, uses a dynamic hostname to host the user's profile picture - meaning that the url was constantly changing. As a result, I had to remove the user's profile pics on their review cards.&lt;/p&gt;

&lt;p&gt;Once I felt confident in my application, I could then deploy it to Heroku! This part honestly sucked because I spent a long time trying to figure out why my callback url wasn't working in production even though it was working in my local. In production, after the user pressed Sign In, it would set the redirect url to the localhost url INSTEAD of the redirect url provided in the Spotify developer portal, causing a callback error 🤬. In the end, I realized that it was because my NEXTAUTH_URL was not defined and so NextJS was defaulting to the localhost url.&lt;/p&gt;

&lt;h3&gt;
  
  
  Potential Add Ons
&lt;/h3&gt;

&lt;p&gt;As mentioned earlier in the introduction, this application is still missing a ton of features. Here are some more features that can be added to this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow feature that allows users to follow others&lt;/li&gt;
&lt;li&gt;Like/Comment feature allowing users to interact with other reviews&lt;/li&gt;
&lt;li&gt;Instead of displaying everyone's most recent reviews, we display reviews only from the user's following list&lt;/li&gt;
&lt;li&gt;Pagination or dynamic scrolling for home page and search&lt;/li&gt;
&lt;li&gt;Allow users to review songs, not just albums&lt;/li&gt;
&lt;li&gt;A section to display the most popular music/reviews/users&lt;/li&gt;
&lt;li&gt;Form Validation&lt;/li&gt;
&lt;li&gt;Mobile responsiveness&lt;/li&gt;
&lt;li&gt;...and more!&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I had a great time building this project and got the chance to learn a lot more about NextJS and GraphQL. I did face a ton of challenging obstacles along the way, but I found that to be extremely rewarding in the end. :)&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>graphql</category>
      <category>react</category>
      <category>spotify</category>
    </item>
    <item>
      <title>Side Project #1 - Crypto FOMO 😱</title>
      <dc:creator>Jonathan Wang</dc:creator>
      <pubDate>Sun, 27 Jun 2021 21:25:18 +0000</pubDate>
      <link>https://dev.to/jwaang/side-project-1-crypto-fomo-553n</link>
      <guid>https://dev.to/jwaang/side-project-1-crypto-fomo-553n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I recently rediscovered my passion for coding after taking a Node.js course and decided to create a fun little side project called Crypto FOMO. You can view it below:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://crypto-fomo.netlify.app/"&gt;Crypto FOMO 😱&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/jwaang/crypto-fomo"&gt;Front End Source&lt;/a&gt;&lt;br&gt;
💻 &lt;a href="https://github.com/jwaang/crypto-fomo-serverless"&gt;Serverless Source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is to make the user wonder how much money they would probably have if they had invested in a cryptocurrency such as Bitcoin a couple years back instead of buying an item such as an Apple Macbook. I actually did not come up with this idea and saw a site similar to this a couple years back but unfortunately do not remember the original site or creator 😢.&lt;/p&gt;

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

&lt;p&gt;Here are the technologies that I worked with for the first time ever 👶:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GatsbyJS&lt;/strong&gt; - This was my first time working with GatsbyJS and I was intrigued with its server side rendering capabilities and ease of setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.JS &amp;amp; Express&lt;/strong&gt; - The whole point of me creating this project was to practice my Node.js skills since I come from a front end background. Turns out, I only had to create one endpoint and ended up putting more development effort on the front end lol.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netlify&lt;/strong&gt; - I really enjoyed working with Netlify and how easy it was to deploy my applications. They practically made deployment dummy proof! One thing that I really liked was that I could link my Github account and trigger automatic builds for every change I made.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netlify Serverless Functions&lt;/strong&gt; - After completing the backend, I started looking into more about serverless functions and realized that it would have been more appropriate to just create a serverless function in the first place. To be fair, this was a new concept to me but ya live and ya learn 🤷‍♂️ I did actually end up converting it to a serverless function without changing too much :)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Development Process
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The first step was to find a reliable and free cryptocurrency API (ya boy is trying to ball on a budget). I tried a couple of them but ended up going with &lt;a href="https://p.nomics.com/cryptocurrency-bitcoin-api"&gt;nomics.com&lt;/a&gt; because it had the best historical data for Bitcoin, starting at around 2010. Also, the API was free and I could make an unlimited amount of requests but the only downside was that I could only make 1 request / second 😞.&lt;/li&gt;
&lt;li&gt;Once I had found my API, I began to create the backend service with Node.js and Express. This part was pretty straight forward: when I hit the endpoint passed in with the coin's ticker, I receive back a response that contains the current price of the coin, how much of the coin the user would have, and how much those coins would be worth in USD. I say coins because the application is able to currently handle BTC, ETH, and DOGE.

&lt;ul&gt;
&lt;li&gt;I also created a Mongo collection and added some items that contained their name, price, release date, and an image url (I ended up not using this field). Every time a user would hit the endpoint, it would return a random item from the database. Keep in mind that the item's release date had to come AFTER the coin's initial release date. The item's price would then be used to calculate how much coins the user would potentially have. Right now, there's only around 30 items in the database. Finding an item's release date as well as their initial release price is pretty time consuming...&lt;/li&gt;
&lt;li&gt;Unfortunately, this request would take at least 2 seconds because it had to hit the API the first time to get the current price of the coin and then hit the API again to get the price of the coin at the item's specified release date. Keep in mind guys this is a free API!!! It is what it is 😤&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Once I had finished creating the endpoint, I began working on the front end. I had heard a lot about Gatsby and Next.js so I decided to give Gatsby a try first. Everything was super simple to set up and even though I had a single page for my application, I thought the way that Gatsby handled routing was really cool as well. I actually haven't touched React in a bit so coding this part was super fun. I stylized everything myself and threw in a lot of ✨ fancy animations ✨. The coolest thing is the theme switcher every time a user selects a new coin. So for BTC it's an orange theme, ETH is a light purple theme, and DOGE is a brown theme.

&lt;ul&gt;
&lt;li&gt;To help alleviate the 2 second wait for each request, I styled the button to say loading and display it as a gray button each time the user would hit the button. Another potential issue I had thought about was what if there were more than 1 concurrent user hitting the button? If that were the case, it would simply display a message saying that the request was rate limited.&lt;/li&gt;
&lt;li&gt;I actually had created my Node.js server within my Gatsby project using a Gatsby plugin, but then I realized this wasn't feasible for deployment so I ended up taking some time to separate the two projects.&lt;/li&gt;
&lt;li&gt;I wished I had created a more legitimate mock up design before continuing with this part because I ended up spending a lot of time trying to decide what I wanted the page to look like as I was developing. That's no bueno 👎&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Potential Add Ons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More coins! The endpoint can already handle most cryptocurrency coins. It just needs to be added to the dropdown on the front end. Technically, I could change the dropdown to an input box and allow the user to type in any coin name.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I had a lot of fun creating this project and deploying it! It's been a while since I've created a side project so this project has definitely awakened something in me 🤓 I have more ideas coming along and can't wait to show it to everyone!&lt;/p&gt;



&lt;p&gt;✌️ jwaang&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>netlify</category>
      <category>react</category>
      <category>node</category>
    </item>
  </channel>
</rss>
