I feel disconnected today. I’m having trouble focusing and feel as if I have more things that I need to do, but I can’t seem to remember what they are. And I have a planner, which I keep looking at to ensure I have nothing else to do. However, I managed to study well and even completed the decimal-to-binary code project. We will build a number sorter for the next project to learn basic algorithmic thinking. While JavaScript can be fun, it can also be frustrating due to its loose typing system (it does not require the explicit specification of different types of objects and variables), and asynchronous nature. I often encounter problems because of misspellings and forgetting to include the semicolon (;) at the end of my code.
At home, I provided Kel with some tech support. I almost joked that maybe I should get paid for it. I did my best with my limited knowledge of RJ-9 and whether we had a headset-to-RJ-9 connector at home (which I doubt we do since we do not need it). But I’m more familiar with the RJ-11, which is the telephone connector.
I got my hair cut on Saturday. It was cut slightly shorter than I wanted, but that’s okay. It will grow back. Karissa also got her hair cut short, and it looks cute. That night, we celebrated Lexi’s birthday with pizza and cake.
On Sunday, Tommy and I took Alexis back to school. We stopped at Walmart so she could do some shopping before heading to her dorm. We even sent her with her cake to get it out of the house and avoid temptation. Before heading home, Tommy and I took a two-mile walk around the campus for our exercise.
I’m considering making a scrapbook of our next trip to Alaska. I can make one of our last trips, but I need to find the ephemera I collected from the trip. I miss scrapbooking. It’s a lot of fun to do.
JavaScript notes…
—————————-
Decimal to Binary Converter steps 81 – 109
Step 81
If you test your code, you’ll notice that your console logs are not in the expected order. Instead of logging free, pausing for a second before logging Code, and finally logging Camp, you’ll see this:
free
Camp
Code
This is because the setTimeout() function is asynchronous, meaning that it doesn’t stop the execution of the rest of your code. All the code in the showAnimation() function runs line by line, but because setTimeout() is asynchronous, free and Camp are logged to the console immediately, and then Code is logged to the console after a one second delay.
One way to fix this is to use multiple setTimeout() functions. Use setTimeout() to log free to the console after half a second, or 500 milliseconds.
setTimeout(() => { console.log("free"); }, 500)
Step 82
While asynchronous, or async, code can be difficult to understand at first, it has many advantages. One of the most important is that it allows you to write non-blocking code.
For example, imagine you’re baking a cake, and you put the cake in the oven and set a timer. You don’t have to sit in front of the oven waiting the entire time – you can wash dishes, read a book, or do anything else while you wait for the timer to go off.
Async code works in a similar way. You can start an async operation and other parts of your code will still work while that operation is running.
You’ll learn more about async code in future projects, but the setTimeout() function is a good introduction.
Add a 1500 millisecond delay before the text Camp is logged to the console.
setTimeout(() => { console.log("Camp"); }, 1500)
Step 83
Now you’re ready to start on the animation itself. You’ll use an array of objects to store data for each frame of the animation.
First, create a new variable called animationData and assign it an empty array.
const animationData = []
Step 84
Next, you’ll create an object to represent the first frame of your animation. Your object should have three properties or keys: inputVal, marginTop, and addElDelay.
inputVal will represent the value of the input each time your recursive function runs. marginTop will be the top margin for DOM elements you’ll add to the page. And addElDelay will be the delay between adding DOM elements to the page.
Add an object to animationData with an inputVal property set to 5, a marginTop property set to 300, and an addElDelay property set to 1000.
{ inputVal: 5, marginTop: 300, addElDelay: 1000 }
Step 85
Recall that the call stack is a LIFO (last in, first out) data structure. This means that, as functions are called, they are added to the top or end of the stack, and as functions return, they are removed from the top of the stack.
Treat your animationData array as a stack and add a new object to it. Your new object should have the properties inputVal, marginTop, and addElDelay set to 2, -200, and 1500, respectively. Remember to add this object to the top of the stack, or in other words, to the end of the animationData array.
{ inputVal: 5, marginTop: 300, addElDelay: 1000 }, { inputVal: 2, marginTop: -200, addElDelay: 1500 }
Step 86
Add another object to the animationData array. Your new object should have the properties inputVal, marginTop, and addElDelay set to 1, -200, and 2000, respectively. Remember to treat the animationData array as a stack and add the new object to the top of the stack.
{ inputVal: 5, marginTop: 300, addElDelay: 1000 }, { inputVal: 2, marginTop: -200, addElDelay: 1500 }, { inputVal: 1, marginTop: -200, addElDelay: 2000 }
Step 87
Now you’ll start building the animation itself.
First, use the document.getElementById() method to select the element with the id animation-container and assign it to a variable called animationContainer.
const animationContainer = document.getElementById('animation-container')
Step 88
Next, clear out your showAnimation() function by removing all of your setTimeout() calls.
(empty)
Step 89
Now you’ll start building the animation itself.
First, set the innerText property of result to Call Stack Animation.
result.innerText = "Call Stack Animation"
Step 90
Next, use the .forEach() method to loop through the animationData array. For the .forEach() method’s callback function, pass in obj as a parameter, but leave the body of the callback function empty for now.
animationData.forEach((obj) => { })
Step 91
Since you have the timing for each frame of animation stored in addElDelay, you can use that value with setTimeout() to set up the delay to add elements to the DOM.
Within the body of the .forEach() method’s callback function, add a setTimeout() function. Pass in an empty callback function as the first argument, and obj.addElDelay as the second argument.
setTimeout(() => { }, obj.addElDelay)
Step 92
Then, use the compound assignment operator (+=) to set the innerHTML property of the animationContainer to an empty template literal string.
animationContainer.innerHTML += ``;
Step 93
Within the template literal, add a paragraph element with the id attribute equal to an empty string.
animationContainer.innerHTML += ``;
Step 94
Next, use string interpolation to set the id attribute to the inputVal property of the current object, obj.
Step 95
Now you’ll add a top margin to the paragraph element.
Add a style attribute to the paragraph element and use string interpolation to set the value to margin-top: ${currMarginTop}px;, where currMarginTop is the marginTop property of the current object.
Step 96
Add a class attribute set to animation-frame.
Step 97
Finally, use string interpolation to set the text of the paragraph element to decimalToBinary(${currVal}), where currVal is the inputVal property of the current object. After this, test out your code by entering the number 5 into the number input and clicking the Convert button.
decimalToBinary(${obj.inputVal})
Step 98
Now it’s time to set up for the next phase of the animation where you’ll update and remove the paragraphs you append to the DOM during the animation.
Add the property msg to the animation object at the top of the stack, and set its value to an empty string.
{ inputVal: 1, marginTop: -200, addElDelay: 2000, msg: "" }
Step 99
Set the value of the msg property to the following string:
decimalToBinary(1) returns “1” (base case) and gives that value to the stack below. Then it pops off the stack.
Note that, since the string itself contains double quotation marks, you’ll need to escape them with a backslash, or use single quotation marks for your string value.
msg: 'decimalToBinary(1) returns "1" (base case) and gives that value to the stack below. Then it pops off the stack.'
Step 100
Next, add the property showMsgDelay with the value 5000 and removeElDelay with the value 10000.
{ inputVal: 1, marginTop: -200, addElDelay: 2000, msg: 'decimalToBinary(1) returns "1" (base case) and gives that value to the stack below. Then it pops off the stack.', showMsgDelay: 5000, removeElDelay: 10000 }
Step 101
For the object in the middle of the stack, add the property msg set to the following string:
decimalToBinary(2) returns “1” + 0 (2 % 2) and gives that value to the stack below. Then it pops off the stack.
Also, add the property showMsgDelay set to 10000 and the property removeElDelay set to 15000.
{ inputVal: 2, marginTop: -200, addElDelay: 1500, msg: 'decimalToBinary(2) returns "1" + 0 (2 % 2) and gives that value to the stack below. Then it pops off the stack.', showMsgDelay: 10000, removeElDelay: 15000 },
Step 102
For the last animation object, add the property msg set to the following string:
decimalToBinary(5) returns “10” + 1 (5 % 2). Then it pops off the stack.
Also, add the property showMsgDelay set to 15000 and the property removeElDelay set to 20000.
{ inputVal: 5, marginTop: 300, addElDelay: 1000, msg: 'decimalToBinary(5) returns "10" + 1 (5 % 2). Then it pops off the stack.', showMsgDelay: 15000, removeElDelay: 20000 },
Step 103
For the next phase of the animation you’ll update the paragraphs with the msg text. Since you have the delays for each step of the animation already, you can add your code to the same .forEach() loop.
Add another setTimeout() function. Pass in an empty callback function as the first argument, and pass in the showMsgDelay property of the current object as the second argument.
setTimeout(() => { }, obj.showMsgDelay)
Step 104
You used the inputVal property as the id attribute for your paragraph elements. Now you can target those the paragraph elements with those ids.
Use the .getElementById() method to select the element with the id attribute with the value of the inputVal property of the current object.
document.getElementById(obj.inputVal)
Step 105
Now that you’ve targeted the correct element, you can update its text after the delay you specified earlier.
Using the .getElementById() method, set the textContent property of the targeted element equal to the msg property of the current object.
document.getElementById(obj.inputVal).textContent = obj.msg;
Step 106
Next, you’ll remove the paragraph elements from the #show-animation element after the delays you specified earlier.
Add a setTimeout() function to your .forEach() loop. Pass in an empty callback function as the first argument, and pass in the removeElDelay property of the current object as the second argument.
setTimeout(() => { }, obj.removeElDelay)
Step 107
Use the .getElementById() method to target the element with the id attribute with the value of the inputVal property of the current object. Then, use the .remove() method on that element to remove it from the DOM after the delay.
document.getElementById(obj.inputVal).remove();
Step 108
Now your animation is complete. When you enter 5 in the number input and click the Convert button, the animation will add paragraphs to the DOM, update the text of each paragraph, and then remove the paragraphs from the DOM.
The last thing you need to do is add the result of converting the number 5 into binary to the page once the animation is complete.
After the .forEach() method, add another setTimeout() function. Pass in an empty callback function as the first argument, and a delay of 20000 milliseconds as the second argument.
setTimeout(() => { }, 20000)
Step 109
Finally, set the textContent property of result equal to calling decimalToBinary() with 5 as an argument. After this, test out your code by entering the number 5 into the number input and clicking the Convert button.
Congratulations! You just finished your decimal to binary converter with recursion.
result.textContent = decimalToBinary(5);