My Second General Assembly Project

Components. Props. JSX. Hooks. How’d you React?

Image 1: ‘Popular’ page

This post took a little longer than planned but here it is nonetheless. Had to redo the entire post as my entire initial draft got lost in Medium’s ether. Tip: SAVE YOUR WORK.

In my previous post, I discussed my first project which was based on jQuery. That was fun, but as they say, you ain’t seen nothin’ yet. This post is an introduction to my project for Unit 2 in my GA course, which uses a library that has become almost essential to learn (or at least be aware of) if you’re developing for front-end: React.js.

React, like jQuery, is based upon JavaScript. Similar to jQuery, React is a library meant to help build dynamic and interactive UI. The key difference is — this is important — React is component-based. This means React is modular, and because of that, updates to the DOM are made dynamically and efficiently rendered/updated. JSX syntax is used to describe what the UI should look like in JavaScript. It is technically not necessary when developing with React, but makes code easier to understand. JSX extends the JS syntax so it is not a new language by itself.

Language: JavaScript! The JSX is compiled into vanilla JS with Babel (some open source voodoo magic). I don’t exactly fully understand how it works, but definitely something I need to check out in the future! One of the quirks about React is that HTML, CSS and JS can all live in one component, which seems to go against the idea of separation of concerns, but… it’s an idea you kind of get used to. Heck, if you use a React CSS Framework it is possible to make an app without a custom styles.css file! (a good thing? a bad thing? what do you think?)

Components: React was built with modularity in mind, and you can build either Class-based components, or Functional Components(FC). Functional components are what I used since that is what I learnt, and found it much easier to grasp and implement especially with React Hooks. This is what a React FC looks like with props. Props are that data received from a parent Component. In JSX, you can include JS logic in HTML with the use of curly braces as shown.

const Hello = ( props ) => {  return <h1> Hello World! My name is {props.name} </h1>;
}

I decided upon filmtrek for three simple reasons: 1. Applying a new language/library/framework learnt on a fun project makes the work much more enjoyable 2. I love films. 3. I love music. That’s it really. I didn’t go out trying to solve world hunger, sometimes starting small is how you get over the fence from the theoretical to the practical. Let’s get into it!

Filmtrek is a frontend project, and was inspired by letterboxd which is an amazing site if you watch a lot of movies. Check out my crappy profile here! It’s a straightforward app, and allows you to find movies based on what’s popular, genre, and perform searches for specific movie titles. Along with the movie results, an album search is also executed which returns a list of soundtracks for the movie (if any). You may also add/remove your favourite movies to a watchlist!

APIs Used:
1. TMDB API
TMDB is a fantastic resource for retrieving all you need to know about movies, TV shows, and cast members. It is free to use and a developer account is very easy to set up. Once you’ve been provided an API key, you can get started right away.

2. Youtube API
A Google Developer account is required to create an API key for Youtube, but it’s trivial as well. You may start retrieving results for video metadata and even embed videos in your app with the help of the Youtube iframe API.

3. Spotify API
The Spotify API required a little more effort to work with due to its need for an additional layer of authentication. A Client ID and Secret is sent in a “GET” request which returns a Bearer token that provides access for a limited time. Any subsequent “POST” requests made for music metadata must include the “Bearer” token in the Authorization header.

CSS Framework Used:
I used Bootstrap as responsiveness was my base requirement for this project. Bootstrap is a component based library that makes it simple to build responsive projects. Its CSS flexbox and grid system is easy to understand and flexible.

Filmtrek was an attempt to combine the aspect of movies and soundtrack discovery into one app. This was because most movie applications or databases are really good at the former, but have little focus on the latter. So why not have both in one?

USP 1:
A search performed for a movie title simultaneously returns a list of results for soundtrack albums matching the query. Once you are done checking out the details of the movie results and watching the trailer, head back to the results page and jump straight into the album which returns you a list of the tracks. Clicking on a track takes you right to your player where you can begin listening immediately.

Image 2: Search Results

USP 2:
Right from the results page, you can start adding to your watchlist immediately! This was a focus point as the app was all about finding your favourite movie, so adding and removing from the watchlist had to be as straightforward as possible.

Challenge One:
Dealing with empty arrays and objects before data retrieval from API — The issue with working with APIs is that it takes some time (even if it is milliseconds) for the request to hit the endpoint and for the server to respond with data. Components which render said data face the issue of trying to find information in arrays/objects that wereundefined as they had not yet been updated in React state. I kept running into errors until I realised that there was a simple solution which you’ll use more often than not: Conditional rendering! Very simply, it looks like this:

{filmObj && <h1>{filmObj.title}</h1>}

In React, statements are not allowed in JSX, only expressions which resolve to a single value. Conditional rendering solves that! Alternatively a library like lodash which comes with many helpful methods to tackle this.

Challenge 2:
Comparing objects using equality — My initial approach of adding and removing films to the watchlist made use of the entire film JS object. This meant making direct object equality comparisons to find matches. You can see the issue with this approach. It works for JS primitives like integers and strings, but fails with arrays and objects due to the two different ways JS tests for equality: 1. Comparison by value 2. Comparison by reference.

With objects and arrays, JS checks if both objects being compared refer to the same location in memory. For two ‘identical’ objects, a falsy is returned if they were initialised at different instances. The solution was simple: Make use of the film id which was unique for every film!

Challenge 3:
React Router behaving unpredictably — React Router in my main App.jsx was not loading the right components even with the Switch and Routes set up. This was because my Context Provider was enclosed in the Switch component which apparently interpretes the Provider as a Router and attempts to load it. The solution was to wrap all the Routes within the Context Provider so all Routes receive the Context! This I think, is best practice anyway as you’ll never know which component might need the context.

There are definitely parts of this project I’d like to improve. Here are some which I feel are important to take note especially for React.

  1. Keeping logic out of the return block — I realised I had quite a fair bit of JS logic in the return blocks of some components which can get messy really quickly and goes against separation of concerns. Something I’d take note of in the future is to perform as much of the logic in the body of the component and reserve the return block for rendering data. Keep it readable!
  2. Improving reusability — React is all about modularity and reusability. I had some constants like endpoints and reducer actions which I hardcoded into the code. Extracting them into their own files would certainly make the code cleaner and adhere to the DRY mantra.
  3. Preloading data — As mentioned, the API calls take some time respond, which causes reflow issues on the UI as elements are loaded. This causes the UI to be janky and while minor, can be a little off putting from a UI perspective (as I was told, sorry UI folks!). Preloading some data would solve this issue.

Unit 2 and project 2 was a fantastic learning experience. React was a fair jump from jQuery and really pushed me in terms understanding novel concepts and coding best practices (i.e functional thinking). It was meant to be a fun project to put what I had learnt to the test, but I am quite satisfied with how this turned out! React forces anyone learning it to think and code in a certain way, especially with regards to code reusability, and has no doubt made me a better developer.

Challenges and areas for improvements were plenty as usual, but if there weren’t any then there’d be no learning! Thanks for making it this far, leave a comment if you’d like to let me know what you thought. See you around for the next project!

A Singaporean perspective. Sometimes I write. Sometimes I code. Mostly I watch lots of movies.

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