what i learned last week: setting up a spa using a javascript frontend & rails api backend
Tags: javascript, rails
Published: 2021-04-28 00:03:40

*Disclaimer: If you are researching ways to set up a spa in your backyard this blog is not for you.* 

Approximately seven months ago I jotted down a couple of JavaScript coding notes into my favorite notebook. As I wrote down exotic words like "boolean" and "concatenation" my mind wandered and I smiled to myself. I had no idea where this journey was going to take me but I knew on that day there was no turning back. 

...Review day for project 4 (I'm in the final weeks of coding bootcamp) is tomorrow and the below image is a great reminder to myself of how much I've grown these past several months.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zvwxog2ztpesqs3662c.jpeg)

To pass the latest phase in Flatiron's Software Engineering program we were tasked with creating a [single page application](https://en.wikipedia.org/wiki/Single-page_application). I had a great time working on the scheduling program from the previous phase so I decided to continue building on that idea and work within the requirements of this project. 

**Requirements**

* The application must be an HTML, CSS, and JavaScript frontend with a Rails API backend. All interactions between the client and the server must be handled asynchronously (AJAX) and use JSON as the communication format.

* The JavaScript application must use Object Oriented JavaScript (classes) to encapsulate related data and behavior.

* The domain model served by the Rails backend must include a resource with at least one has-many relationship. For example, if you were building an Instagram clone, you might display a list of photos with associated comments.

* The backend and frontend must collaborate to demonstrate Client-Server Communication. Your application should have at least 3 AJAX calls, covering at least 2 of Create, Read, Update, and Delete (CRUD). Your client-side JavaScript code must use fetch with the appropriate HTTP verb, and your Rails API should use RESTful conventions.

**Process**

*NOTE: Remember to VERTICALLY build your MVP!*

Step 1. Plan, plan, plan then plan some more! Throughout my time at Flatiron I've discovered that drawing out [diagrams](https://app.diagrams.net/) that represent different aspects of programs I'm creating, including models and object relationships, is extremely beneficial. 

Step 2. Create Rails API backend
   * Generate a new api Rails app
       `rails new <my_app_name> --database=postgresql --api`

Step 3. Build your models: `rails g model <your_model_name>` (Make sure you capitalize the first letter of the model name!)
   * Migrations
   * Model classes
   * Associations

![appt_model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dfo9cubq87sw33fb85f.png)

![schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d93ejhffd882jznyevm5.png)

Step 4. Add routes

```
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  namespace :api do
    namespace :v1 do
      resources :appointments, only: [:index, :create]
      resources :customers, only: [:index, :create]
      resources :hairdressers, only: [:index, :create]
      resources :services, only: [:index, :create]

    end
  end
end
```
Step 5. Add Controllers
   * In your console run: `rails g controller api/v1/<your controller_name>`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwtzoc9iyo6td2i1sqaa.png)

Step 6. Add Fast JSON API Serializer to backend 

[Serialization](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) is the process whereby an object or data structure is translated into a format suitable for transferral over a network, or storage (e.g. in an array buffer or file format).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w5hapzw00mxwze2qczuu.png)

   * Add gem `fast_jsonapi` to your Rails project's Gemfile and run `bundle install`
   * Create Serializer classes
`rails g serializer <your_resource_name>`
   * Update Controller Actions

   _Code below is a public action in the Appointments Controller that retrieves appointment information from the DB and renders data utilizing JSON and a serializer_

```class Api::V1::AppointmentsController < ApplicationController
  def index
    appointments = Appointment.all
    render json: AppointmentSerializer.new(appointments)
  end
end```
   * Add attributes to serializer
```class AppointmentSerializer
  include FastJsonapi::ObjectSerializer
  attributes :datetime, :first_name, :last_name, :email, :hairdresser_id, :hairdresser
end```

**Note**

_JS MANTRA: When some event happens, I want to make what kind of fetch and then manipulate the DOM in what way?_

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ibszuyttas1gmeunl2l3.png)

Step 7. Create separate directory for frontend
   * add an index.html and index.js file to directory

Step 8. Connect API to front end

   * First, In the newly created index.js file I confirmed that the DOM was loaded.

The [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event) event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

   ```document.addEventListener("DOMContentLoaded", () => {
   console.log("DOM Content Loaded")
   })```

  * Fire up your Rails API and confirm that the expected JSON data is present

```class Api::V1::AppointmentsController < ApplicationController  
                     # namespace of route
end```

URL: http://localhost:3000/api/v1/appointments

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cmga3ag8hxaux26mmqsy.png)

Final Product

Github Repo: [https://github.com/reyes2981/appt_program_backend](appt_program_backend)
Github Repo: [https://github.com/reyes2981/appt_program_frontend](appt_program_frontend)