From No Stack to Some Stack (MERN with Spotify)

Shaw Kitajima
8 min readJan 31, 2020

To my many thousands of future fans, I will concede it has been a while since I posted an article. Since the last post, I created a financial web application using Django and Python, made a MERN application with some fun Spotify features, and even wrapped up my bootcamp. Aside from coding, I also had my first Four Loco ever, and threw up from alcohol for the first time. There has been a craze as of late called Dry January, which challenges people to not drink in January. I am not much of a drinker to begin with, but having suffered the nightmares that were Four Locos, I expect I will celebrate Dry February, March, April, and probably even May. But alas, the point of this post is not in discussing my drinking habits. Let’s talk about some code. One quick heads up, while this will detail some of my journey with the Spotify API, this is not a follow-along article on using it. For those interested in using the Spotify API, their documentation is extremely thorough, and their console is perfect for testing.

So, for the final project of my bootcamp, we were challenged to make a full stack MERN (Mongo, Express, React, Node) application that relied on JWT authentication. The application could be full CRUD, or alternatively, consume a foreign API, or have administrative privileges. As you could have guessed by now, I chose to go with the foreign API option, and elected to dabble with the Spotify one. Here are some pictures of the final product!

Welcome Page! (the images used is from https://unsplash.com/@blazphoto)
Home After Logging In!
Adele is Still Trendy

Planning

I have said this before, and I will happily say it forever: proper planning creates a much smoother journey towards a final product than sans planning. If you know what your application should look like, creating the proper components with React comes naturally. If you know what your components are going to require, you know what props to pass down, and which hooks (I heavily implemented useState and useEffect) need to get created. If you know what the front-end requires, you know what the backend needs to create. If you can plan this all out before you write a single line of code, you can combat problems before you are restricted by code that has already been implemented. Having heavily planned my application, I probably only spent 10% of the time debugging. Of course, I did spend a lot of time styling to match my wireframes, and more time than I would like to admit trying to push myself to create the next controller function.

Wireframes are the most important aspect of planning for me — and I make mine using an application called Balsamiq. While it is somewhat pricy at $89 for a desktop copy, I find that it’s intuitive controllers and seriously handy UI components more than justify the expense. Here are some pictures of the mockups I made with Balsamiq!

the image used is from https://unsplash.com/@blazphoto
I like 2Pac

I hope you noticed that my final product closely resembled my wireframes, but you probably also noticed there are some differences. In my opinion, wireframes represent a very rough draft of your application. As you start to actually code your front-end, you will notice that some things just look much better and/or are easier to implement. You should never be bound by your wireframes, but rather, be inspired by them.

Authentication

The easiest way to set up authentication with this application would have been to implement the Spotify Oauth setup, and utilize Passport’s Spotify strategy. However, this was a school project, and the requirements for this application included using JWT (JSON Web Token) authentication, so JWT we used.

Separately, Spotify does not simply hand you an API key that let’s you play around with anything that a user grants you permission to access. Instead, if you choose to go with their cool and sexy “Authorization Code” flow, Spotify will hand you an account token and refresh token for each user that grants you access. Account tokens expire every hour, so you have to submit a refresh request with your refresh token to get a new account token whenever you need one. Secondly, with this flow, Spotify will not allow you to set up your authorization client-side. This means that you have to create a separate backend which will handle all requests to Spotify on behalf of the client. A visual representation would be:

#graphicdesignismypassion

So let’s talk about my first problem with this application. With my application, the user has to sign up for an account with me via JWT. After that, users are asked to authorize us to access their account with Spotify. Users are taken to Spotify, and once access is granted, Spotify shoots a callback to our server with a code that we would then use to ask for the account and refresh tokens. Well, how does my server know which user granted us authorization when we get the callback from Spotify?

Well, we visit the wild, wild west of programming. When users press the prompt to authorize my app with Spotify, they have to eventually redirect to “https://accounts.spotify.com/authorize”. There are a series of query parameters that have to be sent to Spotify for this to work, but one of the optional parameters we can pass in is called “state”.

from the docs

State can be whatever we want it to be, and when Spotify sends back the callback, it will include your state parameter as a query parameter. So why not make it your user’s database id? That’s what I did:

Now when we get the callback, we can access our user’s database id via req.query.state, and add the tokens to that user’s document! Totally insane? Yes. Does it work? Reasonably.

By the way, while I was writing this application, I made some starter code for JWT authentication with a MERN application. Feel free to clone it here.

React Hooks Rock!

I spent a lot of my time during our project week helping my colleagues. They all elected to work with classes for a majority of their pages, and had to deal with passing down state handling functions and remembering which state handler belonged to which class. While I don’t see any performance issues with classes and setState and whatever, I am slowly learning that good code is written for other developers. I will not say that I am good at writing code - my solutions tend to be wild. However, I will attest that isolating state within components with hooks is probably easier to understand from an outside perspective than using classes.

Here is a bit of a big boy, but this is how I implemented the search results page with hooks.

Although reasonably large, the code is not very complicated. This page is really cool because it will fire off a search whenever a user changes something in the search bar. This is implemented by the useEffect method. useEffect takes in two arguments, a function to run, and an array of dependencies. When any of the dependencies change, the function will run again. Therefore, whenever “props.search”, which is updated via an onChange method on the input bar it is attached to, changes, the search will be submitted.

This is really fun to look at when you are already on the search page, and is also conservative on API calls to Spotify when the user is not on the search page, as the search will not trigger until the user is sent to the search page. This is all thanks to us isolating that useEffect method to that page.

However, there is one thing to watch out for when you are working with state, regardless of whether you are using classes or hooks. React works asynchronously, and as far as computers are concerned, foreign API calls take forever to respond. So let’s say you wanted to map over an array that you would populate with an API call. If you don’t initialize that array, your application will error out because it doesn’t see an array to map over. That’s what I’m doing in my useState method.

Closing Thoughts

I could probably go on forever about the Spotify application. This was actually a pretty comprehensive application that almost took a full two weeks to put together. There is fun feature that would add a “community” playlist to a user’s library that was randomly generated from all of my application’s users’ top played tracks. You could add tracks to your library and playlists. The option to either add or remove a track from your library was conditionally rendered based on whether or not your library already included that track. You could play your tracks from any of your available devices (which actually generated a noise complaint from my neighbor, because I was playing music from my home speaker while I was testing from twenty miles away).

But I am writing this article in the library, where the seats are made from a hard wood, and coffee is nowhere to be seen. So let’s close out. I hope that it was a good read, and would welcome any feedback you may have. If you are new to programming MERN applications with foreign API consumption, I fully endorse Spotify’s API as one to learn with. It provides a reasonable challenge by having refreshable tokens, but also has significant documentation for any one of their endpoints. While it is not perfect, my application consumed a lot of Spotify’s features, and those functions all live in the Spotify controller module, so you can take a peek at it for reference here!

Here is a link to the final application if you missed it in the opening.

Humble plug of my Github here.

--

--