Reflection on the Code Challenge

Luis F.
10 min readJul 30, 2020

--

I wanted to take the time to reflect on the code challenge for Mod3 — and break down the steps I used for solving the problem. I am not the best test taker, but I love the process of reflecting and learning from the code and challenge.

Below is a breakdown of my process, as a way to rubber duck to myself and continue to build upon my own understanding.

Backend Set Up

The prompt first started off with 3 core deliverables, as well as a quick guide on setting up the backend. Some important notes to keep in mind as I was reading the readme was that:

— The Base URL for the API will be http://localhost:3000,

— Being mindful of the 2 important end points for the core deliverables. One for the GET Request being the Base URL/films/[:id] and the end point for the patch request being the Base URL/films/[:id]. These will be crucial for our fetch requests in the code to follow!

With that being said, I wanted to start running my set-up for the challenge. I cloned it down from the repo, made a branch with my name, and began to open the the http://localhost:3000 by running my server with the code below in my terminal:

json-server  — watch db.json

This populated the the information from the db.json file from the challenge, with the 15 films! Quick [cropped] snippet of what the code would appear like as objects in the screenshot below as reference, and the specific attributes each film has:

Next, I copied the file path of the index.html file from my VS Code, and copied it into my Chrome browser — Chrome being my go-to for the select elements and console features we will see come up later. And with that loaded — we have our canvas to work with below!

What we will be manipulating and changing with the film data!

Now that we have our preliminary set up done, we can move over to start looking at the deliverables. The first set of deliverables starts with giving a breakdown of what the user should be able to see in regards to the movie details. The movie details include:

  • Poster
  • Title
  • Runtime
  • Showtime
  • Available tickets (**the number of tickets left will need to be derived from the theater’s capacity and the number of tickets sold **— this tells me there will be some logic from these two numbers that will be needed)

With all that being said, I wanted to pseudo code and think to myself what areas of the DOM are we going to be focusing on. We can specifically find the elements by doing inspect on the page, and opening up the Chrome Select Elements feature, but I wanted to visually give a breakdown of my process below. The red being the areas that correspond with the first deliverable that we want to manipulate

Movie title, Runtime, Description (wasn’t in the core deliverable technically but doesn’t hurt to add), showtime, available tickets, and being mindful of the button for the event listener later on.

Unpacking the Code

Below is a breakdown of the code and flow I used in solving this challenge!

First, I went ahead and created a url variable I could refer back to for when the time came for the fetch request only a few lines below. This will make it easier to refer back to!

const url = “http://localhost:3000/films/"

Next, we as a cohort have been using the convention of adding an event listener to the document. This is helpful because it is basically making sure that all the content will be loaded to the DOM first, before any of the functions or logic we put later. This is a method that will save us any hiccups later on, and is a neat trick to help keep the flow of the project smooth.

The code follows as:

document.addEventListener(‘DOMContentLoaded’, () => {

We added an event listener to the ENTIRE document object, with the event listening specifically the DOM Content being loaded, and then the second argument in the addEventListener method is the function and logic we want to follow after the fact.

Going off the first deliverable, we specifically want to see the first movie’s details be shown on the DOM. The screenshot above with the red circles gave insight into what specific areas we will be working with.

But first, we have to make a fetch request so that we have access to the film objects we want to work with.

document.addEventListener(‘DOMContentLoaded’, () => {    const fetchFirstFilm = () => {      fetch(url + id)     .then(response => response.json())     .then(data => { renderFirstFilm(data) })    }     fetchFirstFilm();})

The fetch request in this case harkens back to the GET request endpoint mentioned earlier. The syntax being fetching the information from the URL + an id (in this case being 1 because it was the first). After that, we get a promise from that fetch request and can start using the .then methods. The first .then method is looking to take the response from that fetch request, and then convert it into .json format so that it can be worked with. From there, we chained another .then, taking the response.json() data and referring to it as data, and creating another function that will define later to renderFirstFilm with the argument of data that we received prior. We called the fetchFirstFilm method, but be mindful that we have not defined the renderFirstFilm function yet!

From here, we want to start building out the logic for the renderFirstFilm function that we used in the second .then. This is where following the breakdown of the deliverables comes in handy, because it serves as a guide on which elements we want to find and manipulate.

Below is a breakdown of the code by section of movie details. The important thing to remember as we go down this code, is that the film parameter is the data from the fetch request. This will be important because it means we will have access to the film objects within the scope of this function:

const renderFirstFilm = (film) => {const poster = document.getElementById(‘poster’)
poster.src = film.poster

Starting with the poster, we wanted to grab the element for the poster. I did this by getting the element by id (because id’s are unique, this is was helpful in knowing which to use) by the name of poster, and putting that into a variable called poster. I then wanted to specifically look at the src of the poster (poster.src in this case) and set that equal to film.poster. The reason we are able to call upon film.poster is because film was the argument we have at the top of the renderFirstFilm, meaning we have access to that data and attributes in the scope of our function. So film.poster in this case, is looking at the poster attribute of the first film. This changes the DOM so that the element of poster will now properly show the image of the first film’s respective movie poster!

The next following snippets of code follow the same logic as the first, with the innerText taking the place of .src

const title = document.getElementById(‘title’)
title.innerText = film.title
const runtime = document.getElementById(‘runtime’)
runtime.innerText = `${film.runtime} MINUTES`
const showtime = document.getElementById(‘showtime’)
showtime.innerText = film.showtime
const description = document.getElementById(‘film-info’)
description.innerText = film.description

I specifically used document.getElementByID because all of these elements had specific unique ID’s, and I store them in a respective descriptive variable. Then, following the same logic as poster and having access to the film object as the argument of the renderFirstFilm function, I was able to change the innerText of each variable to be on correspondence to the film object’s specific attribute.

Next up came a tricky part that involved a bit of logic and conversion when it came to the data we received from the films.

const ticketSpan = document.getElementById(‘ticket-num’)// tickets available would be film.capacity string minus film.tickets_soldconst convertedCapacity = parseInt(film.capacity, 10)
ticketSpan.innerText = convertedCapacity — film.tickets_sold

First, we wanted to pull out the ticket span so I went and found the element by it’s Id of ‘ticket-num’. HOWEVER, this part that comes next almost tripped me up. In the object data, film capacity (or film.capacity as we used in the function) was a STRING and NOT an INTEGER. So I had to convert the film.capacity by using parseInt to be able to work with the logic of subtracting the film.tickets_sold from film.capacity. This allowed me to be able to change the innerText of element ticketSpan we pulled out earlier to correctly show an integer.

And voila! Below we have populated all of the information for the first film!

Movie details all correspond to the first movie!

Moving into Event Listener & Update

Having finished the first deliverable of showing all the movie details, now we move into the Event Listener and Patch Requests to work with deliverables:

#2.) Buy a ticket for a movie. The number of tickets sold for that movie should be persisted, and I should be able to see the number of available tickets decreasing on the frontend.

#3.)I should not be able to buy a ticket if the showing is sold out

Tackling deliverable #2 first, we know we have to add an event listener to the Buy Ticket button so that the ticket total changes. And this has to be in accordance to remaining tickets and capacity, which feeds into deliverable #3.

const button = document.querySelector(‘.ui.orange.button’)
button.addEventListener(‘click’, (e) => {
if (ticketSpan.innerText <= 0){
let buttonDiv = document.querySelector(‘.extra.content’);
buttonDiv.innerHTML = “<button>Sold Out</button>”
}
else {
const tickets_sold = film.tickets_sold + 1
let obj = {tickets_sold} //this has to be key:value pair
updateTicketNum(obj)
}
} )}

Given the code above, first I wanted to identify the button. I did this by using document.querySelector(‘.ui.orange.button’), and saving it to the button variable because we want to add a specific event listener to that button. Here is where I wanted to be careful and look at the deliverable for #3, that if there are NO MORE tickets, it will show as sold out and not allow users to buy anymore. Keeping that in mind, I create a conditional within the ‘click’ event listener that if the ticketSpan.innerText — which gives user the amount of tickets left — was equal to or less than zero, to change the button “Buy Ticket” innerText to “Sold Out” which was provided for us as another element. The button text. However, if the if it was above zero, then to add +1 for each ticket bought. I created a new variable for this which would be called tickets_sold that would be equal to the film.tickets_sold +1, to indicate the number would increase by one for each button click until there were no more tickets left.

However — we also want this information to be patched up to the respective film and the database so that it persists, so I created a variable called obj to mirror the structure of a key:value pair of tickets_sold for the film objects for when the request is sent to the database. I called upon a yet to be defined at the time updateTicketNum function with the argument of obj — which was the piece of information we want to update on the object.

const updateTicketNum = (obj) => { 
options = {
method: ‘PATCH’,
headers: {
“content-type”: “application/json”,
“accept”: “application/json”
},
body: JSON.stringify(obj)}fetch((url + id), options).then(response => response.json()).then(data => {renderFirstFilm(data)})}

This is where I wanted to create a patch request, and where we see again the importance of the endpoints mentioned early in the deliverables. Since patch requests work different then GET requests, it is important to specify parameters. If not, it will default to a GET request instead, which is NOT what we want. Since we are calling upon obj as the the argument, this is going to be sending the tickets_sold value that the obj variable was pointing towards, so that it will be upon on the database side.

This means that every event of click on the Buy Tickets button will add one to the total number of tickets sold on the database, and will the be reflected in the innerText of the ticketSpan for remaining tickets. When the number reached zero, the Buy Tickets Button will change to the Sold Out button, to indicate to users there are no tickets available and have the number persist through refreshes on the page. The fetch at the end was created so that given the patch and new changes to the tickets sold and tickets remaining, we can go ahead and call back to the renderFirstFilm function to update the webpage with the data received from the response.

Reflections:

Overall I enjoyed this lab. I originally stumbled because I was completely trying to manipulate the DOM on the wrong side, and is a lesson on why you should always read the ReadMe as a lesson! I know every coder and programmer struggles at times, or doubts their confidence in their code or logic, or may process differently in information through disability under standardized approaches, but being able to reflect on this and my anxiety of assessments was something that made me more comfortable in learning. Coding is messy, coding is tricky, but that is where the fun is! To me I want to be able to understand the logic and being able to go back and do it from scratch and learn the reason’s why through trial and error was what mattered.

Hope this helps anyone who may want to tackle this problem, and provide a framework of my thought process and the why behind the code.

--

--