Happy Monday! Today, I had a productive coding session and completed the challenging Shopping Cart project. I tackled a lot of ‘if statements’, and I feel pretty accomplished. My next coding project is to create a platformer game. For those unfamiliar, a platformer is a subgenre of action video games whose primary goal is to guide the player character from one point to another within a dynamic environment. It’s similar to Super Mario Bros. I’m excited about this new project and the opportunity to learn more about game development, even though it makes me nervous.
The weekend was relaxing, and I spent most of my time outside watching Tommy cook on the griddle. Chris came home on Friday night, so we got to see Everest. She’s growing up quickly, although she won’t be a giant puppy. Merlin, on the other hand, seems to have reached his full size.
Today, my mind feels foggy, making it hard to express my thoughts clearly. We plan to fend for ourselves tonight and have plenty of leftovers from the weekend. I also told Tommy that we are doing weights tonight. We took a week off from exercising and need to return to it.
I’m hungry, but I don’t want to snack. I’m going to make myself some hot tea. I brought the heater into the office. With the wind, the weather is cooler today than last weekend.
JavaScript notes…
———————————-
FreeCodeCamp Shopping cart steps 46 – 60
Step 46
Because of the way computers store and work with numbers, calculations involving decimal numbers can result in some strange behavior. For example, 0.1 + 0.2 is not equal to 0.3. This is because computers store decimal numbers as binary fractions, and some binary fractions cannot be represented exactly as decimal fractions.
We want to clean up the number result from your calculation. Wrap your calculation in parentheses (don’t include the return statement!) and call the .toFixed() method on it. Pass the .toFixed() method the number 2 as an argument. This will round the number to two decimal places and return a string.
calculateTaxes(amount) { return ((this.taxRate / 100) * amount).toFixed(2); }
Step 47
The issue with .toFixed() returning a string is that you want to be able to perform calculations with the tax rate. To fix this, you can pass the .toFixed() call (including the calculation) to the parseFloat() function. This will convert the fixed string back into a number, preserving the existing decimal places.
Pass your .toFixed() call to parseFloat().
calculateTaxes(amount) { return parseFloat(((this.taxRate / 100) * amount).toFixed(2)); }
Step 48
Declare a variable tax and assign it the value of calling your new .calculateTaxes() method, passing subTotal as the argument.
calculateTotal() { const subTotal = this.items.reduce((total, item) => total + item.price, 0); const tax = this.calculateTaxes(subTotal); }Step 49 Update the total value to be the sum of the subTotal and tax values.calculateTotal() { const subTotal = this.items.reduce((total, item) => total + item.price, 0); const tax = this.calculateTaxes(subTotal); this.total = subTotal + tax; }Step 50
You're going to update the HTML in this method as well. Set the textContent of the cartSubTotal to be the value of subTotal to a fixed 2 decimal places. Use template literal syntax to add the dollar sign to the beginning of the value.calculateTotal() { const subTotal = this.items.reduce((total, item) => total + item.price, 0); const tax = this.calculateTaxes(subTotal); this.total = subTotal + tax; cartSubTotal.textContent = `$${subTotal.toFixed(2)}` }Step 51
Following the same pattern as your cartSubTotal, update the cartTaxes to display the tax value, and your cartTotal to display the total property.calculateTotal() { const subTotal = this.items.reduce((total, item) => total + item.price, 0); const tax = this.calculateTaxes(subTotal); this.total = subTotal + tax; cartSubTotal.textContent = `$${subTotal.toFixed(2)}`; cartTaxes.textContent = `$${tax.toFixed(2)}`; cartTotal.textContent = `$${this.total.toFixed(2)}`; }Step 52
Finally, return the value of the total property. Remember your this keyword.calculateTotal() { const subTotal = this.items.reduce((total, item) => total + item.price, 0); const tax = this.calculateTaxes(subTotal); this.total = subTotal + tax; cartSubTotal.textContent = `$${subTotal.toFixed(2)}`; cartTaxes.textContent = `$${tax.toFixed(2)}`; cartTotal.textContent = `$${this.total.toFixed(2)}`; return this.total; }Step 53
Now call your .calculateTotal() method inside your forEach loop.[...addToCartBtns].forEach( (btn) => { btn.addEventListener("click", (event) => { cart.addItem(Number(event.target.id), products); totalNumberOfItems.textContent = cart.getCounts(); cart.calculateTotal(); }) } );Step 54
Your last feature is to allow users to clear their cart. Add a clearCart() method to your ShoppingCart class.clearCart() { }Step 55
The first thing you should do is check if the items array is empty. If it is, display an alert to the user with the text Your shopping cart is already empty, then return from the function.Remember that 0 is a falsy value, so you can use the ! operator to check if the array is empty.
After displaying the alert, return from the function to stop execution.
clearCart() { if (!this.items.length) { alert("Your shopping cart is already empty") return; } }Step 56
Browsers have a built-in confirm() function which displays a confirmation prompt to the user. confirm() accepts a string, which is the message displayed to the user. It returns true if the user confirms, and false if the user cancels.Declare a variable isCartCleared and assign it the value of calling confirm() with the string "Are you sure you want to clear all items from your shopping cart?".
clearCart() { if (!this.items.length) { alert("Your shopping cart is already empty"); return; } const isCartCleared = confirm("Are you sure you want to clear all items from your shopping cart?"); }Step 57
You only want to clear the cart if the user confirms the prompt. Create an if statement that checks if the user confirmed the prompt.In the if statement, set the items property back to an empty array, then set the total property to 0.
clearCart() { if (!this.items.length) { alert("Your shopping cart is already empty"); return; } const isCartCleared = confirm( "Are you sure you want to clear all items from your shopping cart?" ); if (isCartCleared) { this.items = []; this.total = 0; } }Step 58
You also need to start clearing the HTML. Set the innerHTML property of the productsContainer back to an empty string.clearCart() { if (!this.items.length) { alert("Your shopping cart is already empty"); return; } const isCartCleared = confirm( "Are you sure you want to clear all items from your shopping cart?" ); if (isCartCleared) { this.items = []; this.total = 0; productsContainer.innerHTML = ""; } }Step 59
Set the textContent of the totalNumberOfItems, cartSubTotal, cartTaxes, and cartTotal elements all to the number 0.clearCart() { if (!this.items.length) { alert("Your shopping cart is already empty"); return; } const isCartCleared = confirm( "Are you sure you want to clear all items from your shopping cart?" ); if (isCartCleared) { this.items = []; this.total = 0; productsContainer.innerHTML = ""; totalNumberOfItems.textContent = 0; cartSubTotal.textContent = 0; cartTaxes.textContent = 0; cartTotal.textContent = 0; } }Step 60
Your final step is to make your clear button functional. Add a click event listener to the clearCartBtn. For the callback, you can pass in cart.clearCart directly.However, doing so will not work, because the context of this will be the clearCartBtn element. You need to bind the clearCart method to the cart object.
You can do this by passing cart.clearCart.bind(cart) as the callback.
And with that, your shopping cart project is complete!
this.clearCartBtn.addEventListener("click", cart.clearCart.bind(cart));Category: Uncategorized