🍉

RateMyFood React App

As part UCLA’s CS35L class, we were required to build a full-stack app in React JS that satisfied the following requirements:

RateMyFood

To view UCLA Dining menus, students must either visit the UCLA Dining website or download the UCLA Housing app. Our team was frustrated with this process: the menus load slowly, they are difficult to interpret, and there is no way to leave feedback on the food quality. To solve these problems, our team built RateMyFood; an app that aims to replace the clunky process of UCLADining’s website with a mobile solution whereby UCLA students can view and rate dining hall menus.

Architecture

Back end

RateMyFood’s back end is built upon two key pieces of software: our Web-Scraping API and Firebase API. These two APIs work in unison to allow our app to gather, store, and retrieve dynamic data.

UCLA Dining does not maintain a publicly available API to interact with their menus, so we built our own. Our Web-Scraping API using node packages Axios and Cheerio to scrape the multiple UCLA Dining webpages and return food items as an array of JavaScript objects. We achieve this by first using Axios to fetch the response data from each UCLA Dining URL, then using Cheerio (a server implementation of jQuery) to read food data by parsing the HTML. For example, if Epicuria served ‘Athenian Chicken Pizza’ for lunch and dinner, our Web-Scraping API would fetch the data from the Epicuria website and return it as a JavaScript object.

We chose to store our data in a Firestore database (a cloud storage solution offered by Google whereby data is stored in a nested JSON-like structure) and built our Firebase API to act as a bridge between our app and the database. When a ‘submit’ action is placed, such as pressing the ‘Post Review’ button on the New Review Page or liking someone’s review, data is handed off to our Firebase API. Our API cleanses this input and tests it for validity: for example, if our software builds a Review object from input fields and decides some information is missing, it will reject the ‘submit’ action and prevent faulty data from being uploaded. If the data is valid, our Firebase API uploads it to our Firestore database. Our API also allows users to retrieve data, returning Firestore documents as an array of JavaScript objects to be displayed by the frontend.

Front end

Our App’s frontend is built with React JS and styled with CSS, consisting of a 6-page structure with 16 components. This modular approach allowed our group to collaborate effectively: for example, while one developer was working to implement the Recommendations component, I could work on an entirely different part of the project without risking any future merge conflicts. We also defined reusable CSS classes to ensure consistent styling throughout the app.

Additional features

In addition to the features described, our group implemented a suite of tools to ensure RateMyFood provides a far better user experience than currently available methods of accessing UCLA Dining menus.

Search Bar

Found at the top of the Home Page, the Search Bar component allows users to perform a macro search through today’s dining hall menus. The search results appear beneath the input, displaying the all-time average rating for the food (if applicable), the food’s title, location, and meal periods. The menu data is pre-loaded by the backend before the page loads, allowing the filtering of data to appear instantaneous.

Review Filter

By default, reviews are returned by our Firebase API in descending order by date. We also wanted users to be able to sort by rating and by likes, so we implemented a filter into the top right of the Review List component. When a user selects an option from the dropdown menu, the pre-loaded reviews are quickly reorganised into the selected order. To the left of the dropdown, a button allows users to flip the list order between ascending and descending.

New Review Page

We built the New Review Page to allow users to review menu items. Our software automatically populates dropdown menus with data fetched by our Web-Scraping API, which users can then select from to construct a review. This page includes a form validation feature, preventing incomplete reviews from being submitted. Once a user submits a valid review, this page will communicate with the Firebase API to upload the review to the database. The user will then be returned to the Home Page where their review will be visible immediately.

Recommendation Engine

A key motivation for our software was offering users a way to rate UCLA Dining foods. We built the Recommendation Engine component to utilise this data, recommending foods to users based on their previous reviews. If the user’s previous reviews cannot be related to today’s menus, the Recommendation Engine randomly samples foods for the users to try.

Review Likes

Users can like reviews and filter reviews by their number of likes. We believe this will help users to identify the reviews that most accurately reflect meal quality.

Dining Hall Selector

On the Home Page users can select from a list of open dining options. Tapping these icons navigates them to the page of the chosen option, where the hall’s average rating, menus, and reviews are displayed. From here users can also visit the New Review Page, where the ‘location’ dropdown will be pre-filled with the selected hall.

Challenges

One notable challenge we faced was the handling the upload of UCLA Dining data that we had scraped. In the early stages of our app, we were manually running a script each morning to fetch data using the Web-Scraping API and upload it to the database. However, we wanted our app to operate independently, and this was not possible if we were to continue manually syncing the menus each morning. To solve this issue, we wrote an extension of the Firebase API that performs a simple check every time the app is loaded to see if the menus have been synced today, and if not, uses the current user’s device to perform the sync. This generally takes around 3-5 seconds and means we no longer had to manually sync menu data.

Login page
Home page
Home page - live menu search
Home page - recommendations engine
Home page - today’s reviews
New Review page
Dining Hall page
Dining Hall Menu page