I recently finished an application for a frontend internship which included a coding challenge. I actually found it to be fun and learned a lot in the process. Here are some of my insights from the experience.
The main deliverables of this challenge included fetching movie data from an API whenever a user input some search term. I would then need to display those movies along with a button next to each one to allow users to nominate movies. If an item had already been nominated, the button needed to be deactivated. Users could also only nominate five movies, and needed to receive some type of indication that they reached their max. If they wanted, users could remove a nomination from their nominations list.
Besides those main deliverables, we were encouraged to add an extra feature or two, or improve the design. One feature I thought of was simply allowing users to navigate through their returned search results. This is because whenever the data was fetched, unless a page was specified, only the first 10 results were displayed. So, I set out to include next and previous buttons.
On the surface, this feature seemed like it shouldn't be too difficult. However, the more I thought about it, the more intimidated I got. I didn't even know where to start. So, I got out a piece of paper, and started to pseudocode.
This helped so much.
I didn't need to think about syntax or which components the code would live in. I just needed to focus on the bigger picture of what was needed to get this feature to work. Once finished, I managed to accurately plan out what I needed to put into code. This prevented me from forgetting important variables and in general just running around in circles through my components.
Lesson 1: Always pseudocode before tackling a tough feature.
Next, I wanted to add a fun feature. Maybe some confetti to rain down the screen when a user hit five nominations? I found a library called react-confetti and started following a tutorial. Based on the tutorial, I got confetti to rain down the screen when a user's nominations reached five; however, the problem was that the confetti wouldn't stop falling. I only wanted this to be a short animation. I sought out the documentation and tried several methods which did not work. It ended up being a very simple solution. Simply setting recycle to false prevented the confetti animation from looping.
Lesson 2: Slow down, and read the documentation.
I also ran into a weird bug while coding.
In order to disable my nominate button, I set the disabled attribute to nominations.includes(movie)
, checking to see if the movie object was in the nominations array. When first nominating a movie, the disable feature worked fine; however, when I tested an edge case of a user completing a new search for the same movie, the button would become active again. This bug would allow for a user to nominate the same movie multiple times, which I didn't want.
For context, the way I built my search feature is that a new fetch would happen each time my search value changed; I didn't want to store too much unnecessary data. As a result, my movies array was almost constantly updating. (I realize this might not have been the best way to do this. If I had more time, I think I would turn the search input field into a form, so that I only fetched data when a user submitted a search term. I want to minimize those fetches too.)
At first, I found it weird that comparing the movies in my nominations array wasn't returning true when comparing an identical movie that was being displayed in my results. How were these objects not the same? They had the same title, same IMDB ID, same everything. What gives?
The reason hearkens back to a basic fact about JavaScript objects. When you create an object, it is stored somewhere in memory. The object is given a reference which helps locate where it's stored. If you were to create two objects with the exact same data, and then compare them to each other, you'd see something like this:
const objectOne = {data: "some data"}
const objectTwo = {data: "some data"}
return objectOne === objectTwo
=> false
Since these two objects have references to different locations in memory, the computer does not view them as identical.
In my case, my nominate button disabled correctly the first time, because the movie
object being referenced in nominations.includes(movie)
was quite literally the same object saved in my movies array. When I fetched the movie data with a new search, I saved a new movie object to my movies array. Even though the data inside each movie object was the same, this new object had a different internal reference. To the computer, these objects were not identical.
I still didn't want to save all of the movies from the OMDB API to overcome this problem. Instead, I decided to compare the IMDB ID of the nominated movie and the movie in my search results. I put this code in a function that would be referenced by the disabled attribute in my nominate button. The resulting code looked like this:
const checkForMovie = () => {
let disabled = false;
for (let i = 0; i < nominations.length; i++) {
if (nominations[i].imdbID === movie.imdbID) {
disabled = true;
}
}
return disabled;
}
JSX for my nominate button:
<button onClick={clickHandler} disabled={checkForMovie()}>Nominate</button>
We may not always remember these coding basics, but they hopefully come back easier each time we use them. Since I had previously learned this fact about objects at Flatiron School, I remembered after a little bit of thinking. I thankfully didn't have to go on a Google scavenger hunt to find the answer to what was going wrong.
Lesson 3: The basics never go out of style 😎
Finally, because I was creating this project on a bit of a time crunch, I had to prioritize and let go of features and design aspects that weren't important to the overall challenge. I speak of this concept in more depth in my most recent blog post. I'm especially proud of my growth in this area. I started with HTML only - just getting things onto the page, moved on to a basic design, and finally added the extra features that I wanted.
Lesson 4: Prioritize, prioritize, prioritize.
Overall, this was a great experience. I learned some new lessons, was reminded of old ones, and I got to work with an external API! I had never done that before, but this helped make the idea of it less intimidating. I will definitely use external APIs more often in future projects.
What programming lessons have you learned recently? :)
Top comments (0)