How I built Rails API javaScript Project from scratch…

Hi Everyone,

When all this covid-19 issues started I was searching on the internet to see a good web page which can show all symptoms properly and easy to calculate if I have to get the test or go to hospital based on symptoms. But I could not find really basic and clear information about if I have symptoms or not. I was also learning JavaScript at that time when I was isolating. So I decided to make an application to show people if they have a high risk of being infected with a virus or not! Because there was no clear information about symptoms in the beginning of Covid-19 issues and everybody thought that they already had the virus. So I thought I could make an app to clear this chaos. I also thought if I could collect all of that data and see how many people are infected with the virus and see what their age, gender to reserve it after. I was also thinking of stretching the app according to hospital data. Basically if I can synchronize my app to hospital data about their instant bed capacity it may help to stop all the Covid-19 chaos. Actually Covid-19 hunter app is very dynamic for new features. If the scientist determines new symptoms it can be added to the app very easily. It makes Covid-19 Hunter very dynamic. Which is very important for me.

Planning and Building a Rails API

What do I want to build?

My app is about users who are interested to see the list of known Covid-19 symptoms and get an estimated percentage of how infected they are.

Wire framing & User Stories

  • A user is able to create their own data ,
  • A user is able to add symptoms What they consider to have it,
  • A user is able to add their quarantine date and see the percentage number of virus.
  • When user created basic information then click on symptoms what they suspect to have
  • When a user creates symptoms then they will enter start day and end day of quarantines.
  • When the user determines quarantine dates then they will click the submit button.

When users submit a form, User will see the list of known Covid-19 symptoms and get an estimated percentage of how infected they are.

Models, Attributes, Associations

MODELS ASSOCIATION & SEED FILE
  • Before I started my project it’s very good way to work on a diagram. Making a plan with a diagram helps a lot.
  • MODELS
  • I was planning to create 3 models before the build application. The Purpose of my focus is on building vertically for MVP before moving on to the frontend. Eventually my models associations are;
SCHEMA.RB
  • Users has many symptoms
  • Symptoms have many users.
  • Quarantines belong to the user.
  • User Model Attributes :name, :lastname ,:gender, :age attributes.
  • Symptom Model attributes :fever, :cough , :tiredness, :throat, :nose, :other attributes
  • Quarantine Model Attributes :startdate, :enddate

Routes, Controllers, Serializers

Active Model Serializer

Active Model Serializer

An attributes hash must be defined and should contain any attributes that need to be serialized. Attributes must be strings, not symbols. When called, serializable hash will use instance methods that match the name of the attributes hash’s key. When rendering JSON directly, controllers will render all attributes available by default. Active Model serializers work the other way around — we must always specify what attributes we want to include.Having the JSON Viewer Chrome extension installed. This will make JSON data much

User Serializer class

Nested Attributes

I also use nested attributes features for rails and passed in user class for symptoms and quarantines. Nested attributes allow me to save attributes on associated records through the parent. By default nested attribute updating is turned off and I can enable it using the accepts_nested_attributes_for class method. When I enable nested attributes an attribute writer is defined on the model.

ROUTES

routes.rb

Since eventually , my frontend application might be hosted a specific domain i.e :http:covid.com I will want to be my backend routes are indicated associated with my server: localhost:3000/usersBy default, Rails creates routes for the seven default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in my application. I can use the :only and :except options to fine-tune this behavior. The only option tells Rails to create only the specified routes

so I built my relevant routes for MVP in Index & Show and Create. I ran rails routes to confirmed routes and visited localhost3000/users to see if I get errors. Actually it’s easy to work on rails because it always gives you explicit errors. You can easily go and find the errors and fix them.

Controllers

Users_controller.rb
  • I created index method for all my users to make a connection from my backend to use data for frontend and render all my users json:users
  • I created show method for specific user make a connection from my backend to use data for frontend and render all my users json:user
  • I created to Create method to create a new user which would be save in my backend if its saved and render new user json:users
  • I created strong params with private method
  • Built relevant routes for MVP (ex: index, showand create)
  • Visited http://localhost:3000/users to see JSON data
  • Visited http://localhost:3000/symptoms to see JSON data
private    
def user_params
params.require(:user).permit(:id, :name, :lastname, :age, :gender, symptoms_attributes: [:fever, :cough, :breath, :throat, :nose, :other, :user_id], quarantines_attributes: [:startdate, :enddate, :user_id])
end
end
  1. I am rendering all users in the form of JSON.
  2. I am creating a new user based on whatever user_params we get from our frontend.
  3. I am setting out user_params to permit a parameter named id, name, lastname, age, gender,
  4. symptoms_attributes:fever, cough, ,breath, throat, nose, other, user_id,
  5. quarantines_attributes: startdate, enddate, :user_id
  6. . These must be included in the body of the POST or PATCH requests we will be making with JS fetch.
  7. I am setting the status based on the a successful .save

DOM Manipulation, Events, and Fetch using Rails API

Initial set up

  • I created separated directory as index.js and index.html
  • When I created index.js file
  • I started with adding an event listener to DOMContentLoaded with a call back function. The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. Created DOMContentLoaded event listener and console.log(“loaded”) as the event handler to confirm we’ve properly set up the listener.
  • After I created an index.html file with script tag connecting to my I also checked some basic html scope online and try to implement it for my HTML.
  • When I implemented index.html with script tag, I went back to index.js file and started code for my index.js file.
  • I also created index.js, console.log(“in index.js”), and checked for the logged message in my Development tools to confirm the index.html <> index.js connection was established.
  • Initialized a git repo for frontend repository
  • Connect API to frontend!
index.html

FETCH GET REQUEST

According to JS mantra When the DOM CONTENT is loaded i wanted to make a get Fetch and manipulate DOM with rendered data. Then I created a function getUsers to make my first fetch that will make a call to my index and API, made a GET request inside the function and console.log. Invoked getUser function in addEventlistener(DOMContentLoaded). DOMContentLoaded made connection to my backend and front end properly. After I created the fetch get then each step I went over with debugging and see if I can access the related data in my backend to use it on frontend to manipulate DOM based on those data.

I fired localhost3000/users server to be sure the browser to confirmed the expected JSON data is present. So I got all my users on localhost3000/users.I can see the JSON data in the browser.

8- Committed and push this code to my repo on gitHub.

Refactor to make my code DRY

9- When i successfully have all users in my localhost3000/users I created a render function to be sure I am not repeating myself unnecessarily in my code. Ex: Create a render function I can use in both my “read” and “create” functions. I created html tags and inner.text. The innerText property sets or returns the text content of the specified node, and all its descendants append on DOM.

CREATE FORM HANDLER

The next step is create form handler so I wrote a function to handle all forms in a function. So I need to create a variable to query in my html and I also need to create a form tag on my html and I have to give each of them a unique id for specific html tag to append property with for my related data which I would like to show on DOM. I also passed event.preventDefault in the function.

createUsersForm.addeventListener

I also put addEventListener for createUsersform with submit with event(e) and invoked to callback function with createFormHandler(e) which I created function for createFormHandler earlier to create a form when user trigger submit button on DOM they can easily create a form.

event.preventDefault()

(The Event interface’s preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be. The event continues to propagate as usual, unless one of it’s event listeners calls stopPropagation() or stopImmediatePropagation(), either of which terminates propagation at once. After I created all variable for to grab unique id with queryselector for specific HTML tag to append all value of my variable then go to webpage and saw all my users on DOM.

FETCH POST REQUEST

After I successfully get my all user on page the next step is creating fetch POST . But before that I need to figured out how to create nested attributes when I created a new user and just make one fetch for create all my objects. So I re-searched on internet and watched some videos and I thought the best way to created objects to out of my fetch post function . Because I have also set up nested attributes in my user model and users_controller in my backend. I thought its better way to created object out fetch and invoked the function postFetchUser(bodyData) after I created object for Fetch POST . Then I also debugging so see if I can get promise and respond from my backend properly for fetch post.

const bodyData = {name: name,lastname: lastname,gender: gender,age:age,symptoms_attributes:[{fever: feverYes ? 'Yes': 'No' ,cough: coughYes ?  'Yes': 'No' ,breath: breathYes ? 'Yes': 'No',throat: throatYes ? 'Yes': 'No',nose: noseYes ? 'Yes': 'No',other: other ? 'Yes':'No'}],quarantines_attributes:[{startdate: startDate,enddate: endDate}],}postFetchUser(bodyData)}function postFetchUser (bodyData){// console.log(bodyData)fetch("http://localhost:3000/users", {method: "POST",headers: { "Content-Type": "application/json"},body: JSON.stringify(bodyData)}).then(response => response.json()).then(user => {// console.log(user);
})
}

After debugging I also passed renderUser function which I created also for Fetch Get request and I went the page and click to submit and I saw creating form working very well. So I feel like I am already in half way of the project now. Because I made two deliverables for project.

CALCULATED SYMPTOMS END GET AN ESTIMATED PERCENTAGE

But there was important part was coming up how am I gonna figured out how to user the list of known Covid-19 symptoms and get an estimated percentage how infected they are. And I have to write a function for this!. So I dived in a lot of documentation and checked some codes may also help me to write a function and I finally create a function to show the user a percentage number of symptoms they may have on page.

function symptomNumber(symptoms,user){let yesCounter = 0 // set up a counter for my for loop for(let value in symptoms[0]){ iterated all the values of first object in my symptoms array.if(symptoms[0][value]=== 'Yes'){ //if any of values of first object in symptoms is Yes = true 
//increment by one
yesCounter ++
}}console.log(Math.floor(yesCounter/(Object.keys(symptoms[0]).length)*100))
//this code is for to see if the code working in my console in browser
//so its basically converted how many yes or true values in first object's key values in my symptoms array based on object length(i have six keys and values) and multiply with 100 converted for percentage number. displayNumberDiv.innerHTML =`${user.name} ${user.lastname}; May have been infected with Virus `+ Math.floor(yesCounter/(Object.keys(symptoms[0]).length)*100)+ "%"}})

When I saw the code works properly and gave it the correct number according to user entry, I implemented code with inner Html and adding string what I would like to show the user with number.Then i passed symptomNumber function(user.symptoms,newUser) into Post Fetch. Whenever a new user created a new profile they can see the list of known Covid-19 symptoms and get an estimated percentage how infected they are on the Dom.

localhost300/users

It’s time to focus CSS part now. Because I am also getting all users and creating new users on Dom so I can focus how my web page will be look like . So I watched some videos and read some documentation. According those information I created css for my forms and webpage looks much better. So I thought I can go and focus refactoring my codes and also create a class file.

OOJS REFACTOR

1- I created separated branch for my OOJS Refactor

2- created a JS class (ex: class User )

3- Link to the new JS file in my and console.log(“in this js”) confirmed if we successfully link to this.js file.

index.html (ex: <script type=""text/javascript" src="user.js"></script>)

4- Created a constructor that pushes all instances of this into an empty array. Creating a constructor to give us all the attribute copy’s or prototype for my user object. I also defined all attributes on instances of the class.

5- Refactored render functionality by creating a render function in your JS class. Actually I moved my rendered function from index.js to user.js and updated with “this” to render function in JS class .Each new instances I created I will push in User.all =[] I also wanted an empty array to push all instances of”this”in to an empty array

YouTube video Link :https://youtu.be/t-Uld-itTK0

--

--

--

Software Engineer | Ruby on Rails | JavaScript | HTML5 | CSS | PostgreSQL | React | Redux

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

TryHackMe — Chocolate Factory writeup.

Why FlexBox?

Virtual Testing: The Invisible Accelerator

Improve your Chrome by enabling these flags

BigQuery Export has been paused from YOUR-APP for exceeding export limits

Golang: Serverless Microservices with gin

List In Python — Data Structure

Scaling Airflow on Kubernetes: lessons learned

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
Soner Mezgitci

Soner Mezgitci

Software Engineer | Ruby on Rails | JavaScript | HTML5 | CSS | PostgreSQL | React | Redux

More from Medium

The most popular Javascript Library: ReactJs

JavaScript ES6: A crash course on modern JS

JavaScript Closure

I have never had the privilege to use dynamic imports until very recently when I used them to power…