Project Demo: This Or That App | Javascript, HTML, CSS, Ruby on Rails

Sophie G.
5 min readFeb 19, 2021

I created this Single Page Application as part of the Flatiron School Web Development Program to demonstrate an understanding of AJAX calls, which allow the frontend to communicate with the backend without reloading the web page every time we make a request. The frontend is written in Javascript, HTML, and CSS. The Backend API is built with Ruby on Rails.

This web app simulates the This Or That game that people often play with their friends or partners. A game starter designs a set of questions to ask. A game player is presented with two options that they can choose from. Whoever gets the highest scores are the most alike. In this case, you are playing against me. Who knows, we may be soulmates that never met!

As a beginner programmer, I have to say it is not easy to connect the bits and pieces of knowledge without actually implementing it in person. After all, you can only learn so much by reading. But heading straight into a project and fixing every bug that comes out of it, help such much to internalize the learnings. There is really no better way to learn to code.

Step 1: Setup

If you have never created a Javascript app with Rails before, this article can help you get started. I use Atom as the text editor for its integral support for Javascript and Ruby languages. It also has powerful packages to work with Git for example.

Be sure to enable the ‘rack-cors’ gem to configure Cross-Origin Resource Sharing (CORS) permissions. This is needed when say you have frontend and backend on different domains, and they need to talk to each other. CORS is a security feature that tells the browser when requests from different origins are allowed. If CORS is not set up correctly, you should see error messages like this:

“Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at $somesite.”

The browser console is my default Javascript debugging tool. I insert console.log() snippets all the time to check on my functions and variables, which can quickly get confusing as elements pile on. I use Pry on the backend to intercept the Rails program. This works like a miracle when I want runtime insight into the state of my Rails models and controllers.

Step 2: One At a Time

This is the part where it takes patience and belief in the process. I am told that the best practice is

MVP ASAP (Minimum Viable Product, As Soon As Possible)

that is, to build out basic functions as quickly as possible before detouring to advanced, not-essential features. I am also told to

Build Vertically, not Horizontally

that is to test out one model, one controller, one route before moving on to the next. These two principles significantly shortened my development cycle, and also built up my confidence as I work through each problem one by one, when errors are more contained and easier to fix.

In my case, I generated my first model Player with only one attribute :name. I made sure the :index and :create routes work fine with Fetch requests before adding more attributes and validations. Then I thought about modeling the Question, what data I essentially need to present the desired outcome. Finally, I added ActiveRecord associations, which spell out connections between the models and methods they can call on each other.

Database Schema

Step 3: The User Flow

The way Javascript works should closely imitate the user flow. Therefore, it helps to layout user stories before diving straight into functions.

For example, the user of my program:

— Can go through each question and select one option

  • Can click on one of the options
  • Cannot click again or on the other option
  • Can see statistics based on selection
  • Can proceed into the next question
  • Can accumulate score

— Can submit their name

  • Can see their score and result
  • Can submit their name in the form

— Can see a list of top 10 players with ranked scores

  • Can see their name highlighted
  • Can click on each player and see their comments
  • Can double click and hide their comments
  • Can leave a comment and see it posted

This roughly translates to a structure:

document.addEventListener("DOMContentLoaded", function() {
loadQuestion();
askPlayerName();
displayPlayers();
})

where each function is then more closely defined, separated according to the Single Responsibility Principle. Starting with user stories really helps to break down a program into manageable components. Testing with each should not interfere with the others.

Step 4: HTML first, Javascript follows

It is intimidating to start writing Javascript when you have nothing in front of you to work with. From my experience, it is always easier to start with a static template, then figure out how to generate it dynamically. For example, in order to generate cards in their desired format, I hardcoded the HTML:

<body>
<div class="container" id="question-container">
<div class="hidden" id="errors"></div>
<div class="card" id="left-option">
Gryffindor
</div>
<div class="card" id="right-option">
Slytherin
</div>
</div>
</body>

until I am comfortable with the CSS and how they look on the screen. In this way, I am able to generate screens completely from Javascript functions and they look exactly as expected.

It really takes effort to fill in the gaps of knowledge, and I developed a much deeper understanding of Javascript Events, Promises, JSON, and asynchronous functions. It is a lot of work constantly debugging, reading documentation, Googling errors, and checking StackOverflow answers, but in the end, it is an incredible feeling to have learned something. I hope that you find this journey equally worthwhile.

How to Play

To test out the app,

Simply download and cd into the directory
$ cd /path
Make sure to install all dependencies.
$ bundle install

Configure database and start Rails server.

$ rake db:migrate
$ rake db:seed
$ rails server

Open the index.html file in browser and start the game!

View the Github Repository: https://github.com/sophieqgu/js-webapp-this-or-that

Hope you’d enjoy!

--

--