If you've stumbled across this blog post, it is quite likely that you are a Flatiron School student and are looking for examples of projects and/or blog posts. This particular post is intended to provided some tips for getting through this project.
Friendly Reminder: it is normal to feel overwhelmed and/or anxious as you approach this and any project. You are not alone in this feeling, and it behooves you to reach out to classmates, your cohort lead, and/or your educational coach if you should ever feel this way. The Flatiron and general dev community is very supportive!
The Project
The purpose of this project is to take your Ruby on Rails knowledge, and add a layer of complexity to it by creating a one page application using Vanilla JS as opposed to ActionView.
Using fetch();
So you've built your backend API, and upon running your server, you're successfully displaying json. Perfect! The next step is to retrieve this information.
The boilerplate code for making this request is as follows:
fetch('http://example.com/movies.json')//Fetch takes in one argument here://the path whose resource we're trying to retrieve information from..then((response)=>{returnresponse.json();})//we are returned a promise that contains the response object. This is//NOT the information we can use just yet. It is simply the HTTP//response..then((myJson)=>{console.log(myJson);});//This second .then extracts the information we want from that HTTP//response.
To get a feel for the flow of information, we're going to go through the process of fetching information, creating an object from it (in this case, a pin), and then using that object's information to create a child object (a memory).
The models:
classPin<ActiveRecord::Basehas_many:memories,dependent: :destroyendclassMemory<ApplicationRecordbelongs_to:pinend
Here is my API, displaying json rendered by my Rails application.
[{"id":41,"address":"11 Broadway, New York, NY 10004","label":"// Flatiron School <3","latitude":40.7053111,"longitude":-74.0140526}]
What we see is that each pin is stored as an object in an array. Below, jsonData is returning this array, and .forEach is used to comb through each object key for its values below.
fetch(BASE_URL).then(response=>response.json()).then(jsonData=>{//iterates through each location object & sets variablesjsonData.forEach((location)=>{letpinId=location['id'];letpinLabel=location['label'];letpinLatitude=location['latitude'];letpinlongitude=location['longitude'];//creates a pin using above variablespinInfo={id:pinId,label:pinLabel,coords:{lat:pinLatitude,lng:pinlongitude}}dropPin(pinInfo);//We're going to need this later.})
PASS THE DATA!
We're going to pick up where we left off above. The last function called was dropPin, with an argument of the each pin that was created with data from the fetch function.
Our pin is dropped (code redacted to focus on the important matter at hand - passing data). A dialogue box is created when a user clicks on the pin; one of the options is below.
//Each pin carries the following://id, label, coords object(which include lat and lng)functiondropPin(pin){<ahref="#"onclick='createMemoryForm(${pin.id});'>AddaMemory</a><br>}
Let's say our location is Disneyland. We clicked on the pin, and now we want to jot down a memory for this location. TheonClick
attribute in the link fires off'createMemoryForm()'
, with a passed in parameter of${pin.id}
(which holds the value of id for that location). Where does this function come from?
You. It's you. You need to write the function.
Let's do that.
functioncreateMemoryForm(pinId){//First, we declare the function. We have it take in a parameter, and we//name that parameter in a way that helps us remember what we're passing//in.console.log("The function createMemoryForm has been triggered. The form should be displayed below the map.")console.log(`This pin has an id of${pinId}`)//I've logged my parameter and function namein the console for easy//debugging!letcontentContainer=document.getElementById('content-container')//grabbed the container I want to put my form incontentContainer.innerHTML=` <br> Add your memory to this location by filling out the form below: <br> <br> <form onsubmit="createAndDisplayMemory();return false;"> <label for="date">Date (YYYY-MM-DD)</label><br> <input type="text"><br> <label for="description">Description:</label><br> <input type="text-area" ><br> <input type="hidden" value=${pinId} > <input type ="submit" value="Add Memory!"><br> </form> `//created the form}
Can you spot the handshake between our dropPin function and the createMemoryForm function?
Let's do that again, but let's only grab the pieces we need.
// in dropPin();<ahref="#"onclick='createMemoryForm(${pin.id});'>AddaMemory</a>//clicking the link triggers createMemoryForm(); below and hands it pin.id (from above)//in createMemoryForm(pinId)<formonsubmit="createAndDisplayMemory();return false;">//focus on this next line!//the pinId that was handed to this function by dropPin() is given to//the hidden field with an id of "pin_id".<inputtype="hidden"id="pin_id"value=${pinId}><inputtype="submit"value="Add Memory!">
The user goes on and clicks submit. Where are we goingonClick
? TocreateAndDisplayMemory();
! Again, we're going to break this function into several chunks to try and make it easier to understand. Try to spot the handshake!
functioncreateAndDisplayMemory(){letcontentContainer=document.getElementById('content-container')letdate=document.getElementById('date').valueletdescription=document.getElementById('description').valueletpin_id=document.getElementById('pin_id').valueconstmemory={date:date,description:description,pin_id:pin_id}}
Did you see it? Our form had included<input type="hidden" value=${pinId} >
The following line of code grabs that valuelet pin_id = document.getElementById('pin_id').value
and then we use all the information from our form to create a memory object.
constmemory={date:date,description:description,pin_id:pin_id}}
Do you see the critical piece? We grabbedpin_id
! What ispin_id
on our memory table?
A FOREIGN KEY!!!!!!!!!!!!
What this means for us is that our memory will be sent to our database and given its own unique id. That memory will also know who it belongs to. Done over and over again, each new and unique memory will have a foreign key that corresponds to its has_many resource. Cool, right?
Let's finish creating a memory for this pin.
fetch(BASE_URL+'/memories',{method:"POST",body:JSON.stringify(memory),headers:{'Content-Type':'application/json','Accept':'application/json'}})
We send a POST request, and hand our newly created memory to the body of the request :body: JSON.stringify(memory)
.then(response=>response.json()).then(memory=>{contentContainer.innerHTML=""contentContainer.innerHTML=` <br> Date: <br>${memory.date}<br><br> Description:<br>${memory.description}<br> <a href='#' onClick='editThisMemory(${memory.id})'; return false;>Edit this Memory</a><br> <a href= "#" onClick= 'deleteThisMemoryWarning(${memory.id});'> Delete Memory </a> `})
Then we executed our remaining .then functions to return the newly created memory. We can expect to see that memory's date, and description.
If you're reading closely, you'll also notice that we have two new links with onClick functions:
<ahref='#'onClick='editThisMemory(${memory.id})';returnfalse;>EditthisMemory</a>
and
<ahref="#"onClick='deleteThisMemoryWarning(${memory.id});'>DeleteMemory</a>
Each function is handed a memory id. Can you guess what happens next?
.....
We write those two functions, and continue the handshake, of course.
Some hot tips:
HOT TIP 1
When POSTing, PATCHing, DELETEing, you don't necessarily need to use the two .then's that are part of the boilerplate fetch code. Only use your .then's if you need data returned to you so that you can display it.
HOT TIP #2
BUILD YOUR CODE AS YOU GO, AND GIVE VARIABLES SEMANTIC MEANING.
Naming things in a way that is easy to read, and that simply makes sense, will save your life. Especially if you build the functions you need as you go.
&& that's all, folks!
As always, thank you for reading, and please feel free to reach out with critiques, comments, suggestions, and/or questions.
Keep it real, y'all!
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse