Happy Valentine’s Day! Ok, so it’s a gimmicky day to say I love you to someone special when you should say it every day. But I still like the idea of it. It’s a day of romance. In history, some say it’s a celebration of St. Valentine’s death. According to History.com, Valentine’s Day is when the Christian church may have decided to place St. Valentine’s feast day in the middle of February to “Christianize” the pagan celebration of Lupercalia.
I still have some leftover chocolate from Christmas that I’m eating. There have been changes in the household over sugar, so there will be no candy this year. I still have my leftover chocolate, which is almost gone now. Karissa wants to go to the store tomorrow and get candy. It’s a good idea since everything will be on sale. I’m trying to finish my chocolate so I don’t have any more temptations in the house and can eat better. I must resist the urge to ask Karissa for some of her candy cause she will share. And I mustn’t take advantage of that.
Therapy was complex today. Yes, we discussed my relationship with Kevin and my time in Germany. Don’t get me wrong, Germany was superb—the castles and visiting Paris and Salzburg. Going to the market every day for fresh bread was a treat. I’m surprised I didn’t gain any weight when I was there. My parents came up for a visit, and that was fun. I took so many pictures of my time there.
As I was saying before, we got married young. I don’t recommend getting married at such a young age. But we took our time in Germany to have fun. And in some ways, I wasn’t entirely proud of my behavior in Germany. My mind went a bit wild there. If I had any agency at that age, I would not have gotten married or gone to Germany. So it was a good and bad thing. It was nice being on my own. But it was scary at the same time.
A few things happened while I was in Germany. One was that I had my first miscarriage. I was only able to carry the baby for a month before I miscarried. The mental pain was worse than the physical pain. I found out that aspirin was developed in Germany when I went to a German pharmacist in Frankfurt for some pain meds. I don’t think I was ready for a baby yet, but it was still heartbreaking. I partied with and without Kevin since he was on the field so much. Imagine a bunch of wives getting drunk while their husbands are away. It was lonely sometimes being in a foreign country alone while your husband was off with the Army. I couldn’t drive cause I didn’t have a German license, but we did take the train a lot to get off base. Or to go to another base. Kevin, his brother, and I traveled to castles and other places. Then there is one more thing that happened in Germany that I can’t bring myself to discuss. For one, many people would know who I’m talking about. And I can’t do that. Only a few people know what happened. But it made me feel ashamed and guilty since I’m the one who allowed it to happen. Yes, I’m being vague, but I can be ambiguous in my journal.
But we had a lot of fun too. Even when we had to pay 2000 German Deutsch Marks for our phone bill, Kevin ran it up using the internet. Learning the history of Germany and surrounding countries was my favorite part of our three years there. Since Kevin was away often, I spent much time at the base library. No one ever came to the library so that I could use the internet all day there, and no one would say anything. Then I’d go home and read or watch movies and play SimCity. That is when I wasn’t working. I worked at Burger King on base and at the base movie theater. The base we lived on is not there anymore. It closed down in 2007. We were a tiny base. When the guys went to the field, the base would be empty. Some wives would fly home when their husbands went to the field or war. I stayed on base since I was working.
Tonight, we are having pad Thai for dinner. That is a good Valentine’s Day dinner. 💕
JavaScript notes…
—————————————
Calorie Counter
Step 62
In programming, null is meant to represent the absence of a value. In this case, if the user enters an invalid input, you want to alert them and then return null to indicate that the function has failed.
Still within your if block, set isError to true and return null.
function getCaloriesFromInputs(list) { let calories = 0; for (const item of list) { const currVal = cleanInputString(item.value); const invalidInputMatch = isInvalidInput(currVal); if (invalidInputMatch) { alert(`Invalid Input: ${invalidInputMatch[0]}`); isError = true; return null; } } }
Step 63
Remember that return ends the execution of a function. After your if block, you need to handle the logic for when the input is valid. Because your if statement returns a value, you do not need an else statement.
Use the addition assignment operator to add currVal to your calories total. You’ll need to use the Number constructor to convert currVal to a number.
The Number constructor is a function that converts a value to a number. If the value cannot be converted, it returns NaN which stands for “Not a Number”.
Here is an example:
Number(’10’); // returns the number 10
Number(‘abc’); // returns NaN
function getCaloriesFromInputs(list) { let calories = 0; for (const item of list) { const currVal = cleanInputString(item.value); const invalidInputMatch = isInvalidInput(currVal); if (invalidInputMatch) { alert(`Invalid Input: ${invalidInputMatch[0]}`); isError = true; return null; } calories += Number(currVal); } }
Step 64
After your for loop has completed, return the calories value.
return calories;
Step 65
Now it’s time to start putting it all together. Declare an empty calculateCalories function, which takes a parameter named e. This function will be another event listener, so the first argument passed will be the browser event – e is a common name for this parameter.
function calculateCalories(e) { }
Step 66
You will be attaching this function to the submit event of the form. The submit event is triggered when the form is submitted. The default action of the submit event is to reload the page. You need to prevent this default action using the preventDefault() method of your e parameter.
Add a line to your calculateCalories function that calls the preventDefault() method on the e parameter. Then, reset your global error flag to false.
function calculateCalories(e) { e.preventDefault(); isError = false; }
Step 67
Your function needs to get the values from the entries the user has added.
Declare a breakfastNumberInputs variable, and give it the value of calling document.querySelectorAll() with the selector #breakfast input[type=number]. This will return any number inputs that are in the #breakfast element.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll("#breakfast input[type=number]"); }
Step 68
Using that same syntax, query your number inputs in the #lunch element and assign them to lunchNumberInputs.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); }
Step 69
Following the same pattern, query for your number inputs in the #dinner, #snacks, and #exercise elements. Assign them to variables following the naming scheme of the previous two.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]'); const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]'); const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]'); }
Step 70
Now that you have your lists of elements, you can pass them to your getCaloriesFromInputs function to extract the calorie total.
Declare a breakfastCalories variable, and assign it the result of calling getCaloriesFromInputs with breakfastNumberInputs as the argument.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]'); const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]'); const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]'); const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs); }
Step 71
Now declare a lunchCalories variable, and give it the value of calling getCaloriesFromInputs with your lunchNumberInputs.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]'); const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]'); const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]'); const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs); const lunchCalories = getCaloriesFromInputs(lunchNumberInputs); }
Step 72
Following this same pattern, declare variables for the number inputs in the #dinner, #snacks, and #exercise elements. Assign them the appropriate getCaloriesFromInputs calls.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]'); const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]'); const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]'); const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs); const lunchCalories = getCaloriesFromInputs(lunchNumberInputs); const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs); const snacksCalories = getCaloriesFromInputs(snacksNumberInputs); const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs); }
Step 73
You also need to get the value of your #budget input. You already queried this at the top of your code, and set it to the budgetNumberInput variable. However, you used getElementById, which returns an Element, not a NodeList.
A NodeList is an array-like, which means you can iterate through it and it shares some common methods with an array. For your getCaloriesFromInputs function, an array will work for the argument just as well as a NodeList does.
Declare a budgetCalories variable and set it to the result of calling getCaloriesFromInputs – pass an array containing your budgetNumberInput as the argument.
function calculateCalories(e) { e.preventDefault(); isError = false; const breakfastNumberInputs = document.querySelectorAll('#breakfast input[type=number]'); const lunchNumberInputs = document.querySelectorAll('#lunch input[type=number]'); const dinnerNumberInputs = document.querySelectorAll('#dinner input[type=number]'); const snacksNumberInputs = document.querySelectorAll('#snacks input[type=number]'); const exerciseNumberInputs = document.querySelectorAll('#exercise input[type=number]'); const breakfastCalories = getCaloriesFromInputs(breakfastNumberInputs); const lunchCalories = getCaloriesFromInputs(lunchNumberInputs); const dinnerCalories = getCaloriesFromInputs(dinnerNumberInputs); const snacksCalories = getCaloriesFromInputs(snacksNumberInputs); const exerciseCalories = getCaloriesFromInputs(exerciseNumberInputs); const budgetCalories = getCaloriesFromInputs([budgetNumberInput]); }