Build a Javascript Single Page Application

This project was my 4th project with Flatiron School. I had to build a SPA(Single Page Application) using Javascript, CSS and HTML as the frontend. Specifically, we had to build an asynchronous Javascript using tools like Fetch API or AJAX. This means that I had to use Rails as an API to render JSON (Javascript Object Notation) that Javascript can fetch and manipulate without needing to refresh the page. This is a common technology that many websites use to dynamically present data.

I will breakdown the steps using 2 parts, one for the backend and one for the frontend.

Part I: The Backend

First of all, I will go over how to build the backend, which will be pretty fast as we already built a project using Ruby on Rails. I had to make sure to create a folder for the whole project, and then inside of this folder, create a folder for the backend that I called “restaurant-style-back-end” and push it to a new repository on Github :

  1. Once created, the set up is fairly easy. You create a new rails app using the command: ‘rails new . — api’ (the dot is a way to create it inside this new folder and not adding another folder)
  2. Set up your models. I decided to go with a restaurant model that has a name and city, that belongs to a style that has a name. I decided to start very easy at first as I was not very confident, and later added an image and a link_url to my restaurant. To set up both of these models, I used scaffolding which set up 90 % of your controllers (CRUD actions), tables, routes and models.
  • Model: Things I had to do was to add the associations in my models, create a custom association writer method for the restaurant to accept the style attributes.
  • Controller: Add the style_attributes custom method in the strong params and in index and create actions, remove “created_at”, “updated_at” and “style_id” from render and include the “style” using:
except: [:created_at, :updated_at, :style_id], include: [:style]
  • Don’t forget to add rack-cors gem to your gemfile just by uncommenting it (The CORS spec allows web applications to make cross domain AJAX calls without using workarounds such as JSONP) and also update the cors file in your initializer to include all (*)

That is about it for the backend, run “rails db:migrate” once you are satisfied with your tables and seed some data if needed.

Part II:

For the frontend, I created a new folder inside of my project folder that I called “restaurant-style-front-end” and created a new repository on Github: This is my main repository that includes a link to the backend in the Readme.

  1. Inside of this new folder, I created folders and files like so:

2. In index.html, I used the command “html:5” that creates a html template for the document. I added some “script” tags to connect the html to my javascript files, keeping in mind that the order matters:

3. The global.js will contain my global variables. A global variable has global scope: All scripts and functions on a web page can access it. For example, I have my constant “main” that will get the element by its “id” in the html:

const main = () => document.getElementById("main")

Note that I used an arrow function expression. An arrow function expression is a compact alternative to a traditional function expression, but is limited and can’t be used in all situations. In this case it is fine and makes the code looks cleaner.

4. Next the restaurant.js in my models folder. This file is home to the restaurant application code. It has a class Restaurant that is the blueprint of the restaurant Object. It has a constructor method so that we can create an instance of a restaurant with special attributes (name, city, image_url, website). By using or to define properties in our constructor method , we can also refer to these properties within other methods of our class. This allows us to return dynamic information based on the unique properties we assigned back when an instance was created. These instances will be stored in an array using a static method. Static methods are class level methods - they are not callable on instances of a class, only the class itself.

5. New instances of a restaurant will then be saved when created and pushed into this array using the save and static create method:

6. The render function is the way to create our html using Javascript. We first declare a variable to create the element, then use the “.innerText” to print it, and append it to the adequate parent:

This function will also create the “edit” and “delete” links using “addEventListener()” method that attaches an event handler to the specified element. This method takes 2 parameters, the first parameter being the type of the event, the second being the function we want to call when the event occurs.

Both functions are declared within this file and will have similarities like preventing the default on the event (e.preventDefault()) so that the page keeps from refreshing when the Fetch request is made. We then find the id of the restaurant that we want to edit or delete, and in the case of the “editRestaurant method”, we render the edit form for this restaurant and then we do a fetch patch request to update the element updating our Rails Api. In the case of a delete event, we prevent the default, find the restaurant by its id, send a fetch delete request to our Rails Api and then render the restaurants. All this happens in a blink of an eye.


This was definitely a fun but intense project to build. There is a lot more that I could have covered in this blog but I tried to do a resume of the steps that I took to build this project. There was a lot of refactoring to make my code DRYer and a bit of css to make the page look nicer.

French guy who recently moved to the United States. I am also changing career after having worked 13 years in restaurants. I will be going into coding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store