3 months ago, I had no experience in coding. Though I had zero understanding of what it was to code, it just felt like something I could be good at so I signed up for a boot camp and have just completed my first project.
The Project
I was tasked to create a Single Page Application using JavaScript, HTML, and CSS. I wasn't married to any idea, but I knew I wanted to create something that I would actually use. I decided to move forward with a basic media listing application that uses a free API of existing TV shows to archive and categorize what a user: has watched, plans to watch, and scores the watched media. There is a similar application built into IMDB but it's incredibly limited. I wanted to make my iteration of this idea intuitive, functional, and appealing. I gave myself one week to complete this project.
Mistakes
This being my first time creating something, I was eager to begin. I had an idea for how I would do everything in my head, but I never formally organized the infrastructure of this application before starting. I told myself I'd make a minimum viable product and then go from there. Once I got to this point, I fell into a dangerous loop of telling myself that I would continue building functionality and refactor code later.
A week came and went and though I was able to get all of the functionality that I wanted out of this project, the code wasn't as clean as I'd hoped.
1) Married to JSON
I had already learned how to initialize a JSON server as a means to save and update data. It wasn't until completing my project that I considered alternatives that would better suit my application. I actually planned on using this myself to archive a list of my favorite TV shows, but going through the hassle of initializing a server to do so makes it inconvenient to use. Given that there isn't much data that needs to be stored, I likely could have just used an object, or searched for other, more convenient, storage solutions.
2) Separation of duties among functions
It is important to me that my code is legible, flexible, and functional. I created one function in particular that I believed at the time was sacrificing some legibility for more flexibility. I see now that I needed to separate these duties among multiple functions.
This function was not only asynchronously creating a modal box and overlay with all the bells and whistles, but was also filling data from both the API and the JSON server, and doing an additional fetch to determine the episode count of a particular show. This led to JavaScript processing redundant information, being difficult to read, and being difficult to debug. Due to this oversight, I had to come up with solutions that, although they may work, are less optimal than it otherwise could be.
Learning as I go
Although my mistakes did cost me an optimal final product, I was definitely learning from my mistakes as I continued the project.
1) Making it work
Due to the way my modal function was written and not having the time to refactor it, I had to find a way to balance a function that receives different data under the same argument. I decided to use an OR operator when declaring a variable with this data so that I could avoid conflicts of information. In one instance, I had to use a nested if statement to make this work.
Note: Whenever totalepisodes is undefined, epCount will be correct. Whenever totalepisodes is defined, epCount will be incorrect. This is because the IDs between the JSON and API are not shared.
// Episodes determined by db.json
console.log(show.totalepisodes)
// Episodes determined by API
console.log(epCount)
const epInput = document.createElement("input")
epInput.type = "number"
epInput.name = "number"
epInput.min = 0
epInput.max = show.totalepisodes || epCount
epInput.addEventListener("change", (e) => {
if(!show.totalepisodes) {
if (episodes.childNodes[1].value >= epCount) {
select.value = "Completed"
}
}
if (episodes.childNodes[1].value >= show.totalepisodes) {
select.value = "Completed"
}
})
2) Flexibility done right
When I was writing the code to render filtered shows determined by status (watching, planning, etc.), I made sure to do it right. Rather than creating a function that makes a bunch of empty divs and then fills them conditionally, I created the empty divs in HTML and now I could use one function to fill ALL of them conditionally. This is a legible, flexible, and functional solution that I was very proud to find.
Creates cards to a specified container id, based on the condition of an existing element.
function filterBy(status, id) {
fetch("http://localhost:3000/shows")
.then((res) => res.json())
.then((data) => {
let filteredShows = data.filter((element) => element.status === status)
for(show of filteredShows) {
createCards(show, id)
}
})
}
Creates header for rendered cards
function createTitle(headText, headId) {
let container = document.getElementById(headId)
let header = document.createElement("h1")
header.className = "filter-header"
header.textContent = headText
container.appendChild(header)
}
Application of functions during list creation
function createList() {
fetch("http://localhost:3000/shows")
.then((res) => res.json())
.then((data) => {
if(data[0] === undefined) {
createTitle("Search for your favorite shows to start your list!", "watching-head")
} else {
createTitle("Watching", "watching-head")
filterBy("Watching", "watching-container")
createTitle("Completed", "completed-head")
filterBy("Completed", "completed-container")
createTitle("Planning", "planning-head")
filterBy("Plan to watch", "planning-container")
createTitle("Dropped", "dropped-head")
filterBy("Dropped", "dropped-container")
}
})
}
Not making the same mistake twice
This experience taught me that having a plan is vital to keeping your code optimal. As soon as I get something to work, I should refactor it immediately to benefit the code in legibility, flexibility, and functionality.
Top comments (0)