The making of lyricist - A Lyrics Getter Site!

The making of lyricist - A Lyrics Getter Site!

ยท

10 min read

Who am I?

Hello!๐Ÿ‘‹ I am a 15-year-old who really loves python and am interested in Javascript as well!


A Screenshot of The Site -

lyricist-ss.PNG


Why I Decided To Code Lyricist

Making Lyricist really just started out as a project to learn more about javascript. I wanted to learn how to -

  • Make a backend
  • Make GET and POST requests in JS to make API calls
  • Scrape with NodeJS
  • Build a beautiful looking site from scratch without following a tutorial

This project was heavily inspired by Gee842's Lyrica.
A link to my Lyrics Website - https://mulitate4.github.io/j_lyrics_app/


The Process of Building Lyricist.

Starting out

I was really pumped to make a lyrics-getting site in Js. I had already coded for 5 months in Python and had decided to learn Js for a project (I'm building a game in pure python without any external libraries at the time of writing!). So I wanted to learn how to make API requests in Js using NodeJs and make a backend as well.

I did not know what NodeJS was actually used for when I started out. I knew it as a standalone JS compiler and a package manager, but little did I know that those packages were actually used for making a backend! I used to think that these packages were for the frontend and was really confused while trying to get them to work.

So, I started off by reading the Genius API's docs. This is what I was going to be using to make the site. The first problem I noticed was that there was no way to get lyrics directly from the API. This is understandable, as returning Lyrics is quite heavy, especially for some songs (looking at you RAP god).

Figuring out the API was probably the easiest part. Building the backend off of it was harder for me, as this was my first project with a complete backend.

A Small Explanation of what Frontend and Backend is.

For those that do not what Backend and Frontend are.

  • Frontend is what is shown to the User. Input and Output are displayed on the Frontend. For example, You give a computer input to calculate 2+2. This data is then sent to the backend to be processed, and after receiving the solution, it is displayed again on the frontend
  • Backend is what does the heavy lifting of the entire operation. It receives data from the Frontend (UI/Website), calculates what is needed, then sends that calculation back to the Frontend
  • Frontend (Input) -> Backend (Analyzing/Processing) -> Frontend (Output/Display the data to the user)

The First Major Problem

I was really excited, so I started off by installing Axios and Cheerio. Axios for fetching the page and Cheerio for processing and extracting the data. But here's where I went hugely wrong. I tried to get these libraries to work on the frontend. I tried getting a hosted library, tried using require(['Axios', 'Cheerio']), but after a complete DAY of searching, I got nowhere.

Then my friend Gee482 explained to me that NodeJS was actually used for building a backend. That's when the clarity hit me. This is when I started making ACTUAL progress on the app. This was already one whole day into the project. I wouldn't call it wasted, but I made no progress.

On the second day, I was developing mostly the frontend and was pretty much done with it according to my standards. I finished with a few finishing touches, such as making the site more responsive to handheld devices, and called it a day.

The Backend

The backend was sort of a headache, but I liked building it nonetheless. My first approach was to send the query (song as a String) to the backend using HTTP requests. In my backend I accepted the data that was sent by the Frontend, and passed that for processing.

The request from my Frontend was basically -

lyrics = axios("http://localhost:8000/" {
    method: "POST",
    data: songName
});

This worked fine while I was hosting it locally, but I had to change it later due to Heroku's limits.

You can view the rest of my code at this github repository - Here.

Async/Await Hell

The rest of the code consisted of a TON of async/await functions. Looking back, some of them needn't have been async, but that's something for another day. The project actually helped me understand Async/Await quite well. Earlier, I was REALLY confused as to what it did, or how to actually return the data to the variable, or how to wait till getting the info was complete (As in my case!).

let resp = await genius.search(songName)
  .then((resp) => {  
  // Extract URL from response
    let songUrl = resp.hits[0].result.path;
    fullSongUrl = baseUrl + songUrl;
    return fullSongUrl;
  }).catch((e)=>{console.log(e)})

This is one of the examples where I needed to use Async/Await. Earlier, I was really confused as to why I was getting a promise object rather than an actual response. Then I decided to read the MDN Docs (Extremely Useful btw) and understood async/await much, much better.

After understanding those, the rest of the project went smoothly! (Well, getting Cheerio to work took some time, but it was due to my own stupidity ๐Ÿคฆโ€โ™‚๏ธ)

Hosting.

When the project was complete locally, I decided to take a break and host the project sometime later. That later came over 2 days later, when one of my friends asked me if they could use the site.

This started my journey of hosting on Heroku. I had already hosted my Discord Bot on Heroku, so I had some experience hosting. This time, instead of the CLI, I decided on using my github repo itself to run the backend, as I really like github, and it's much easier to version control.

So I wrote my procfile, and pushed to github. From heroku, I linked my account and deployed from master. Excited I opened my Frontend hosted on Github, but of course, ran into a ton of errors. The first main error was CORS. CORS sucks, unless you know what you are doing. So I adding a few lines of code ->

  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);

and the error was gone! No more CORS ๐Ÿ˜”. I deployed to github again, redeployed to Heroku, aaaaaand, the lyrics weren't loading. ๐Ÿ˜ฉ. After an hour of debugging, I realized that the data which was sent with the POST request, wasn't actually going through! This was really annoying, and there was absolutely no way I could solve it.

So I decided to tinker with my code, and decided to use search URL based query. If you don't understand what I mean, api.blah.com/q=queryGoesHere. In this, queryGoesHere is what I would be using as my songName to search for the lyrics. Getting this to work took some courage, as I did not want to shift my whole project from invisible data to Url based data. But this turned out for the best


What I learnt

  • AJAX requests (I didn't use them, but still understood them)
  • Making a basic HTTP server
  • HTTP requests
  • Async/Await
  • Making API calls in JS
  • CORS
  • Encapsulating all the above -> Backend Building with NodeJs

That's it!

That was my complete project all ready, done and dusted. Responsive on Mobiles, Nice little UI and ofcourse, proper functionality. This project helped me understand a ton of things and helped me realize that coding takes COURAGE. Yup! See you in the next post!