Javascript with Rails API project

Christian Cain
6 min readApr 20, 2020

For my fourth round of projects at Flatiron School, we we’re tasked with building a single paged application. It was a daunting, yet fun challenge!

The requirements were that we write a webpage using OO JS, and have that webpage handle asynchronous calls to our backend Rails API. It was a great opportunity to practice both crafting & handling AJAX calls, and using ES6 syntax.

The Inspiration

I was originally inspired by SWAPI, a VERY robust Star Wars API. I appreciated being able to look up practically any tid bit on the series. Though I was not up to calculating how much credits the Death Star costed (1 trillion).

This use of data was inspiring, though given the time constraints of the project, I didn’t have time to both collect data & build a solid app. So I Googled “top apis”. Lo and behold, Blizzard’s card game Hearthstone was one of the top used APIs in 2019. One of my favorite games!

So I figured a deck builder would be a fun challenge!

Getting the data

I decided that my first step should be to make sure that I could get the data, so that I knew what I was imagining was even possible.

I spent an entire day playing around with Hearthstone’s own API, but was greatly troubled by not being able to make requests to their endpoints without having to go through a client-side oAuth process. I quickly realized that there are A LOT of awesome community led APIs that served the same information. I ultimately decided to go with omgvamp’s hosted on RapidAPI for data because of its querying system, and HearthstoneJSON for images.

“I’ll take that”

Now that I had a source for the data, I then needed to get it into my own database so that I could model it, and work with it.

I wrote a script that would handle the request to the RapidAPI endpoints, and then re-formatted the data in a manner that was more inline with what I needed. I then saved that data to a local JSON file.

This was probably the feature of my app that I’m most proud of. In the future I would like to have this process automated to account for upcoming expansions!

Creating the API

I was blown away by the simplicity of creating a new API using Rails. Using the app generator with the “ — api” flag provided me with a barebones Rails API.

I originally wrote my data fetching script mentioned above in a solo file. Now I needed to incorporate it into my app and have it run as a Rake task. Then I wrote models & migrations for both Heros and Cards. Next I needed a seeds file that would take in the previously mentioned JSON file, and create instances based on that data using Mass Assignment.

Next I wrote controllers for both Heros and Cards that served the necessary data in JSON format. Once again, Rails made this super simple!

def show  hero = Hero.find_by(id: params[:id])  if hero    render json: hero, except: [:updated_at, :created_at]  else    render json: { message: "Hero not found" }  endend

Just like that I had a working API!

On to the Fun Part

Now that my API was working, it was time to bring the data to life on the client side.

I began by sketching out what I wanted my application to look like. First on paper, then in an editor. Having something to visually refer back helps me out so much!

I wanted the user to be able to build decks using cards based on their choice of hero. I also wanted to have a robust filtering system.

Rendering the Cards

Another thing that I found incredible interesting about this project, was how you are able to model data on the back end in one language, and then again on the front end in an entirely different language!

Once the page loaded, I needed to send AJAX requests to the server, and then model the Hero & Card data using OO JS.

Once I had the data modeled and the instances stored locally, I could then go on to writing JS to generate the HTML needed to display said cards. I decided to write class functions that could render out HTML objects for each individual Card instance. Really interesting stuff!

Building the Filtering System

Now that I had 1,000+ cards being displayed on the screen, I needed a way to be able to filter through them & only display the right cards at the right time.

Having messed around with React previously, this kept reminding me of the use of state! How you have dynamic HTML that changes based on some factor. After much trial & error, I decided to have a global “card_config” object that stored information about what cards to display.

let CARD_CONFIGS = {  set_type: 'Classic',  class_type: 'Hunter',  query: {...}};

I then crafted a single callback function that would be triggered anytime that the displayed cards needed to be changed. Given information based on the card_config object, and what event triggered the callback, I was able to write a short control flow to handle this decision making process.

This is another feature I am most proud of.

Lets build a deck!

Now that I had a way to filter through the cards, it was time to give the people what they’ve been asking for. The ability to build a deck! Lol.

I created a JS class for the Deck, and provided a few functions that handled adding cards to the deck, and removing them. Adding & removing data in the deck instance was pretty straight forward. It was the HTML side of the house that was complicated.

When adding a card, there where certain factors I had to consider. Are there already 30 cards? Are there already 2 copies of the same card? Is the card a legendary? Where does this card fit numerically & alphabetically?

Keeping with the design principles I learned from MVC, I decided to let the class handle the adding & removing, and have my index file handle the HTML manipulation based on the response from the class.

function addCardToDeck(card){  let resp = DECK.addCard(card);  if(resp.status) {    if (resp.amount === 1 && !resp.isLegendary) {      // Adding second card...    } else {      // Initial render for the card...      if (resp.isLegendary) {        // Adds a star if the card is a legendary...      }    }    // Update card count for deck...  }}

I now had a working app that I’m proud of!

https://github.com/SenseiCain/hearthstone-deck-builder

Takeaways

Javascript is awesome. Its loosely defined guidelines lets you write code freely, and it is constantly evolving. OO in JS is especially interesting, and can allow you write much cleaner code.

AJAX calls are like having elevator music. You still have to wait to get where your going, but if done correctly the wait is not as bad.

Future Updates

I would like to have the seeding process run automatically, maybe once a week, so that when I check back in 6 months new cards will be displayed. I’d like to have a carousel of images be displayed as options for choosing a Hero. I’d like to be able to save & load decks created.

This was a fun project, and I learned a lot. I hope to write more things like this in the future.

Thanks for taking the time to read! Cheers :)

--

--