Portfolio Project 16: Web Development

For Day 97 of the 100 Days of Code course, the goal was to create an online shop. Of all of the Flask projects that were completed in this course, this was definitely the most complex of them all. This project took me about two and a half weeks to complete.

Online shop's homepage.

This project has several goals and steps that were taken to complete the project.

Here is a general overview of the checklist steps that I took to complete this web app project.

  1. Create and generate all web pages with HTML and CSS.
  2. After the web pages were created to my liking, I then incorporated Flask and Jinja to render the pages.
  3. Feeder insects that were used to render the shop were created from a dictionary.
  4. Once I verified that the shop was rendering properly using a dictionary, I then created a database with three separate tables, a user’s table, products table, and a shopping cart table.
  5. After the skeleton for the website was created, I then proceeded to work on creating the functionality for all the web routes starting with the pages that would send emails, the contact me page and the order confirmation page.
  6. The next functionalities that were added were to add functionality to create an account as well as log in to the website.
  7. Functionality was then added to add items to a user’s cart as well as update those items and remove them from the cart entirely.
  8. The last major step in this project was to add functionality to process payments. For this capability, I used the Stripe API to allow users to submit a payment for their order.

This project had many pieces that needed to be integrated so there was a good amount of trial and error in completing this project. Some of the biggest hurdles encountered were:

  1. Stripe API integration
  2. Database design
  3. User Cart Bugs🪲

Stripe API Integration

Integrating the Stripe API with my Flask application took a bit of tinkering to properly render the payment page. Using the sample code listed on Stripe’s documentation worked great using their sample code and files but when trying to integrate the code into my Flask application, I encountered issues with the route not rendering properly.

I then decided to build the API integration from scratch using the instructions found on testdriven.io’s website. After following the instructions on this guide, I was able to properly route the Stripe payment page into my application.

stripe payment page

Database Design

Designing the database to use for this course took a bit of thinking since this was the first database I used for the portfolio projects that used a foreign key.

The Users table was populated when a user signed up for the website.

The Products table is populated from the dictionary of items composed on a separate .py file when the Flask application runs. If the Products table is already populated, the function that populates the table does not execute, preventing the table from having duplicate entries.

The Shopping Cart table was the table that required trial and error to get right. When a logged in user added an item to their cart, their cart item was added to this table. Item information was gathered from the Products table. Upon initial testing, everything appeared to work great but when testing with multiple users, I encountered a bug that would allow only one instance of a product to exist in the shopping cart table. If another user had that item in their cart, that item would not be added to the table for the currently logged in user.

To fix this issue, I had to redo the table so that only the user information was pulled from the Users table. When an item was added to a user’s cart, a row would be populated with pertinent information from the Products table. Redoing the Shopping Cart table also made coding some of the POST routes a bit less complex for the Flask application, reducing the number of lines of code.

ShoppingCart Table screenshot

User Cart Bugs 🪲

Perhaps going hand in hand with the Shopping Cart table, rendering and modifying a user’s cart had many bugs.

As mentioned in the Database design section, one of those bugs was that items would only exist in one user’s account until those items were deleted. After redesigning that table, I was able to properly get identical items to exist in multiple user’s carts.

Also tied to the database issues, were that multiple item were added to a user’s cart if items already existed in a cart. This issue was caused due to a for loop that looped through each entry in a user’s cart. The more items that existed in a cart, the more duplicate items would be added to a cart, essentially doubling it with every addition.

One other feature that required some trial and error was modifying the quantity for items in user’s carts. This occurred before and after the Shopping Cart table redesign. Before the table was modified, items were being modified based on their index. To fix the issue, I used a for loop with an if statement to make sure that the proper item was being modified. I also noticed this issue occurred after the redesign but this was fixed after the bug that prevented items from existing in multiple carts.

vs code screenshot

This project was a beast compared to some of the other ones in this course. Of all the Flask applications I created, although complex, I feel as if this one was the cleanest code written for all of them. Especially when looking back at the Coffee shop project, I could see the improvement in how I coded the HTML pages as well as the Flask routes. For the Flask apps, this was also the first one I created where the tables all interacted with each other.

After some headaches and head scratching moments, this one was very satisfying to complete.

View the project’s code as well as screenshots on my Github repository!

shop items