poradrian / honzi

Web app that displays stats from your Spotify profile

Home Page:https://honzi.herokuapp.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

About

This web app displays some of your Spotify stats such as top artist/tracks, the latest played tracks and audio features (acoustincness, danceability, liveness etc) by fetching data from the Spotify Web API.

Lessons learned

While working on this project I gained a better understanding about building and deploying a full-stack web app. The most important lessons learned involved code structure and organization, and my newfound understanding of the OAuth authorization flow, React hooks, API integration and Git management.

Back-end

Tools: NodeJS, Express, Heroku.

The topics explored on the server-side were: REST APIs, HTTP requests, and the implementation of the authorization protocol OAuth, to allow users to log in with their Spotify account.

The server in NodeJS was created using the Express framework, instead of the native http module that ships with NodeJS. Using Express made some parts easier to implement (such as routes) and another good thing about express is that it has a healthy community with plenty resources to help building out API's.

Spotify's OAuth Client Credentials Flow

Before implementing the OAuth flow, it was necessary to integrate the app and manage the Spotify credentials in the Spotify Developer Dashboard. After the app was registered, the last step before initiating the 0Auth flow was to get the client id and client secret strings from the developer dashboard and add them in the .env file at the root of the project. These unique strings are needed to identify and authenticate a particular app when requesting an access token.

Front-end

Tools: React (with hooks), React Router(v6), Windi CSS

The build tool for setting up the development environment for React was ViteJS, which provides fast development experience for modern web projects by using a dev server with Hot Module Replacement (HMR) over the native ES module.

On the front-end, the project was configured to run both the client-side and server-side code at the same time by adding the postinstall npm script to the root package.json and make it run npm install in the front-end directory.

The Spotify OAuth access token retrieved from the Node server was passed to React with the help of the URLSearchParams() constructor that creates and returns a new URLSearchParams object. localStorage was used to store the access and refresh tokens. Once the localStorage was set up, fetching and displaying data from Spotify was done with the help of the useState and useEffect hooks.

A different React hook used was lazy in the App.jsx component which is the first component rendered when the users loads the application. The component renders the AuthenticatedApp if there's a user, or else UnauthenticatedApp component. If a user checks out the application for the first time, they're not going to be logged in, so the UnauthenticatedApp component will be rendered. In that case, all of the code for the entire application was loaded under the AuthenticateApp which is unnecessary because the user cannot see/interact with anything from the application. By lazy-loading the AuthenticatedApp, only the UnauthenticatedApp component can be loaded at first, then the AuthenticatedApp will load once the user is logged in. lazy requires a Suspense fallback to display when the code is loading and it also requires the modules imported to be exported by default. It's true that the impact is not big here because the optimization was done in a small project like this but in a bigger project it will be more beneficial.

import React, { lazy, Suspense, useEffect, useState } from 'react';

import { FullPageSpinner } from './styles/lib';

const AuthenticatedApp = lazy(() => import('./Authenticated'));
const UnauthenticatedApp = lazy(() => import('./Unauthenticated'));

function App() {
 const [token, setToken] = useState(null);

 useEffect(() => {
   setToken(accessToken);
 }, []);

 return (
   <div>
     <Suspense fallback={<FullPageSpinner />}>
       {token ? <AuthenticatedApp /> : <UnauthenticatedApp />}
     </Suspense>
   </div>
 );
}

The styling was done with the help of Windi CSS, an utility-first CSS framework, similar to Tailwind. One of the advantages of a CSS framework with predefined utility classes is that you don't have to come up with names for the classes, and using media queries is easier. On the other hand, I had to rely on vanilla CSS to add some custom styling in a few places.

Code Style

I used the automatic code-formatter Prettier and ESLint, a static code analysis tool for identifying problematic patterns found in ECMAScript code. Shortly put, ESLint is more concerned about what the code does and Prettier about how the code looks like. These tools allow the developer to focus less on things like "what is the spacing or is there a need for a comma or semicolon in a particular place, is a variable well named? are you using good accesibility practices", which can help with writing better code faster by taking care of some issues automatically. Both tools offer customization but I used the default config because I don't have strong opinions on this matter and I prefer letting the recommended automatization take care of it.

There can be an overlap between the two tools because ESLint can worry (not as good as Prettier) by itself about how the code looks but you can set them up so they can work together in a good way.

source for the landing page picture: https://unsplash.com/photos/wKAOlN4A644

About

Web app that displays stats from your Spotify profile

https://honzi.herokuapp.com/


Languages

Language:JavaScript 93.3%Language:CSS 5.1%Language:HTML 1.6%Language:Procfile 0.0%