Saturday, April 18, 2020

JavaScript Recipe Box Project

For our most recent bootcamp project, we were tasked with creating a single-page application that uses Rails on the back end and JavaScript on the front end. For me, this project had an especially steep learning curve. I remember just 10 days ago feeling completely confused by what I was supposed to do. I thought I had understood what the terms back end and front end meant, but in actuality I did not. I had no idea how to organize my JavaScript code other than in one index.js file, and I didn't really understand how to use a fetch request. Although I still have a ton to learn, I now feel like I have a much better grasp on all of those concepts.

I created a Recipe Box application, where the user can store their recipes from around the web on recipe cards (with links and images). The user can also add notes to a recipe -- for instance, allowing them to remember that those chocolate chip cookies need more salt next time, or that the zucchini frittata needs an extra 10 minutes of cooking time over low heat. And, in my favorite piece of functionality, there is a weekly menu planner on the right side of the screen with boxes corresponding to each day of the week. The user can drag a recipe card over to the menu planner, allowing them to plan out their meals for the week.

Here are some of my main conceptual takeaways from the project:

  • Front end v. back end: Prior to this project, I would have said that the "front end" refers to the aesthetic aspect of a web app (how it appears in the browser), and that "back end" refers to all of the functionality. I quickly learned that this was wrong! Functionality is a broad term and some functionality does, in fact, live in the front end. Clicking on a button to make a form appear is a front end feature because it requires no communication with the server. Clicking on a button to save a new recipe, on the other hand, does require persistence to a database and thus communication with the Rails server, making it a "back end" feature.
  • Classes on the front end: It was quickly apparent that my JS code was a mess, but I wasn't too sure how to fix that. When we created our Rails project, the separation of concerns was much clearer and it was easier to decide what code went where (in fact, Rails didn't give us much of a choice!). In JS, it's possible to keep all of your code in a single index.js file -- which of course results in disorganized code that is difficult to maintain. I decided to mirror each of my back end model classes (i.e, recipe.rb) with a front end class (recipe.js) that is responsible for the front end functionality related to those database records. As an example, the recipe.rb class on Rails side is responsible for performing validations and title-casing recipe names before a new record gets persisted. The recipe.js class on the front end is responsible for loading all of the recipes from Rails, generating the HTML for each recipe's card, and then rendering that HTML to the DOM.
  • Updating the DOM v. updating the database: I was incredibly excited to get my drag-and-drop feature working, allowing the user to drag a recipe card into the weekly menu planner to organize their meals for the week. (This was a very useful drag-and-drop tutorial!) I spent way too long admiring the fact that the recipe name would *magically appear* in the menu planner ... and then I realized that as soon as I refreshed the page, it was gone! Yet again, a lesson in the difference between updating the DOM versus updating the actual database. In this case, I actually needed to create a new database table to keep track of the days and their associated recipes. I created a save button that triggered a PATCH fetch request, updating each day.recipes array in the database.

This was the most complex and gratifying bootcamp project so far; I'm proud to have created a web app that I actually want to use and am going to attempt to host this one so that others can also use it! Thank you again for joining me on this journey, and feel free to check out my GitHub repo here.