In the streaming age, there are more options than ever for movie nights. An issue I’ve heard many of my friends and family face is that it is that much harder to decide on a movie to watch because of the overwhelming number of choices. For my final project at Flatiron, I wanted to create something that would help make that decision process easier. To do so, I surveyed people about the things that are most important to them when looking for a movie. Overall, I found that people could often only narrow it down to the genre of movie they wanted to watch. The details that mattered most to them when making a decision were an interesting description of the plot and — most importantly — that it was available to stream easily. Overwhelmingly, people were more likely to watch a movie if they had heard positive things about it from another person. I based the functionality off of this research to create an application that takes user recommended movies and allows users to sort recommendations based on genre. When viewing the list of recommendations, the user is provided with a plot description as well as the name of the streaming service where it is available.

An Overview of the Stack

Before we dive into the details, let’s take a look at the different technologies used to make the application:

  • What to Watch relies on an API built with Rails as its backend.
  • The frontend was built using the JavaScript library React and uses Redux for state management.
  • For styling the user interface beyond what React provides, I used Material UI.

Creating an API to Store the Data

Since What to Watch is reliant on user submittable data, a place to store that data is one of the most important parts of the application. For this, I decided to build my own API using Rails. While there are existing movie APIs out there, none seemed to have exactly the information I wanted. I chose to use Rails because it keeps things simple when creating a backend and is easy to connect to using React. For this project, in particular, I found I only needed one table. I created a movies table with columns for each field I knew I’d want to be displayed to the user: title, description, genre, and streamer.

Adding A Recommendation

To allow users to make recommendations to be added to the backend and displayed to other users, I created a submission form as a component. I used text area fields for the title and description entries. However, I decided to use a drop-down selection for both genre and streamer as I wanted to ensure users only selected from the list of supported genres and streaming services. Above the code for the form itself, I set the state to equal an empty string so that the state of the fields starts empty before a user inputs anything. I also created two functions — one to handle changing the state and one to handle submitting the form. The first sets the state so that the field in question is set to the value of what the user has entered. In other words, if the user types “Harry Potter” into the title field, the state of title would be changed to Harry Potter:

To make this work, we set the text field’s value to {this.state.title} and give it an onChange of {this.handleChange}. The handleSubmit() function, unsurprisingly, handles what happens when we submit the form. It references an action I created — this action uses fetch with a post method to add the movie, pulling from our recently changed state, to our database.

Displaying Recommendations

Once recommendations have been made, they need somewhere to be seen. There are two ways a user can see a list of recommendations: by genre, or the entire list. To display the entire list, I created a const called movies that mapped a new array with props associated with each field. This array pulls from my stateless<Movie /> component, where I defined the card-like style for each entry. I also wanted the list to be sorted in alphabetical order, so I set another const named sortedMoviesthat uses the .sort() function on the previously created movies to alphabetize it. While in theory there should never be zero movies since I seeded sample data, I wanted to make sure that if that ever did happen the user did not just get a blank page. To ensure there is a user-friendly view no matter what, I utilized an if else. In it, I say that if the number of movies in sortedMovies is greater than zero, display the const{sortedMovies} as defined previously. If not, display a stateless component called <NoResults /> that displays a message saying that no movies match the criteria you were searching for.

What we see when entries are available vs what we see when no movies are available for that criteria.

The pages that filter by genre are very similar. They have the same const and if else statement with one addition: instead of just sorting our data, we also filter it to only display entries that match the genre in question. I used .filter() to do this. For example, the page that displays the Sci-Fi and Fantasy options has this line of code: const filteredMovies = movies.filter(movie => movie.props.genre === “Sci-Fi/Fantasy”).

Displaying all movies vs displaying one genre only

Stateless Components

While many of the pages mentioned so far rely on state, stateless components are incredibly helpful as well. These components are static in nature, and therefore do not need to rely on state. In What to Watch, I created stateless components to handle my navigation bar, about page, footer, an error message, and a message to display when no records are found.

Challenge: Material UI

One unexpected challenge I faced during this process was using Material UI to style my application. I had used Materialize CSS in previous projects and I had assumed the implementation would be essentially the same. However, I quickly learned that was not the case. While Materialize has certain class names it relies on for CSS purposes, Material UI for React uses separate components to create styling. While the implementation wasn’t difficult per se, there were a lot of differences in the naming conventions and customization options. I spent a lot of time reading and comparing the documentation for the two, watching YouTube videos (I highly recommend this playlist by The Net Ninja if you’re looking for a comprehensive understanding of how to use Material UI!), and completing tutorials to ensure I understood the process before using it in What to Watch.

Wrapping Up

While it is always satisfying to finish a project, this one is particularly meaningful to me as it is my final project for my software engineering boot camp at Flatiron School. What I love about this final project is that it allows me to put together everything we have learned throughout the course. If you had told me at the start of this program when we were first learning the basics of Ruby that I’d be able to create my own API soon, I wouldn’t have believed you. But now, I’m able to do so with ease and I’m able to implement that backend into a complex frontend as well. I’m excited to have learned so much and to see it come together in a project I’m so passionate about, but even more excited to see what comes next.

You can check out a video demo below, or take a look at the project on GitHub here.

Software Engineering Student @ Flatiron School by day, TV/Film Script Analyst by night. NYC via FSU.

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