---
tags: mstu5003, tinker, js
---
# TINKER - Javascript Part II
<!--
- See repository: https://github.com/jmk2142/TodoMSTU5003
-->
Participants: Michelle Avenant, Daniel Hiterer, Saphy Ratner, Ayse Unal, Yiran Wang
- See demonstration: https://codepen.io/msa2218/collab/JjywRNp
- Tinker Markdown: https://hackmd.io/zJmA8GKJR5-Oe2Zy4r1wqw?both
<!--
For this week, the actual Markdown file is not available via Github Gists. I have included it within this week's Tinker repository along with the rest of the code. It is called `README.md`. You might want to `IMPORT` the markdown into hackmd.io to use that tool (recommended.)
To get access to this code, and the actual Markdown to play with, you can use Github to CLONE the repository using the Github GUI Client. You can get the idea of what repositories are in my Youtube Video:
## Github: How to clone my repository
You'll want to start with the video overview:
https://youtu.be/QOXhN90d9Mk?list=PLn93-yl6k7zUkSFNI8MQqmIVn017z8vKO
Since you want to copy MY repository, once you have the Github GUI Client installed - you can do so with one click of a button. Just click on the Clone or download option, then **Open in Desktop** and that will automatically open it up in the Git GUI. (See Below)

Keep in mind that since you are cloning my repository, you will only be able to commit changes to your local computer. You will not be able to _sync_ or _push_ changes to my Github repository - for obvious security reasons. (You wouldn't want just anyone to change YOUR code.)
If you would like to use Github for your work in progress, what you can do is **_FORK_** my repository first. (See _FORK_ button under account picture.) This will create a copy of this repository under your account name in Github. You can clone YOUR version of this to your local computer, then commit and push to your account to your heart's content. :smiley_cat:
---
-->
## Devtools
You will also want to watch this video on the `console` as we will be using it extensively to Tinker this week.
General Video on Console: https://youtu.be/GAqOggzH_GE?list=PLn93-yl6k7zUkSFNI8MQqmIVn017z8vKO
One of the most important tools we'll use is the `DEBUGGER`.
:::success
**Debugger Demonstration and Youtube Video**
<!--
REPO: https://github.com/jmk2142/Debugger
DEMO: https://jmk2142.github.io/Debugger
-->
CODE: https://codepen.io/jmk2142/pen/RwZErre
DEMO: https://cdpn.io/jmk2142/debug/RwZErre
YOUTUBE: https://youtu.be/RdF7j4no0Ts
:::
I recommend that at some point, you watch these demonstrations and use these tools to explore the Tinker.
:::info
In order to use `console.dir(object)` and see the object property/values, make sure your console setting is set to DEFAULT.

:::
## Tinker GIST: TODOS
> Good bye, "Hello World!"
`Hello World` is probably the most common introductory program around as it's so simple.
```javascript=
alert("Hello World!");
// Or alternatively...
console.log("Hello World!");
```
Unfortunately, it's not very useful. It doesn't really show the range of different programming concepts and to be quite frank, it's boring. Many beginners like us are interested in creating interactive applications and this requires a range of programming concepts.
1. HTML Elements
2. CSS
3. Variables
4. Operators
5. Functions
6. Control Statements
7. Events
8. Data Structures + Data (e.g. Arrays, Objects, Booleans, Numbers, Strings)
And you really cant get a sense of how these things work together with a 1 line program like `Hello World!`.
### Enter TODOS
Some clever programmer realized this and probably thought:
> What's the simplest, _real_ program I can build that will incorporate all the important aspects of a basic interactive program?
And the **TODOS** or **TODO LIST** program was born.
The beauty of TODOS is that it has everything in a pretty simple package. It can be solved using a variety of different strategies and can be created to be _simpler_ or _more sophsiticated_ depending on ones needs. It tends to now be the defacto standard for demonstrating a full interactive application.
Beginners AND advanced students alike build TODO apps as they learn new things. For example, our TODOS Tinker is designed to demonstrate the base JS concepts with a few _stretch_ challenges embedded in it. In my regular practice, when I have to learn a new library or framework, I will probably start by viewing an existing TODO app built with that specific library to see how that library works. Sort of like how you might compare a basic HTML page with a Bootstrap page (of the same content) to be able to compare and contrast the two. If you're interested, you can briefly look at [this page](http://todomvc.com/) which is an archive of the TODO application built in various different frameworks.
And this is where I am hoping to take this class, the culmination of all the things we've been working towards - to understanding this first, real, interactive program and hopefully - you can apply some of these concepts in your own works.
## Tinker Tasks
In this tinker, were going to:
1. Review prior concepts in this new context:
- Variables, functions, events, and arrays
2. Observe, analyze, and study new concepts:
- Control statements (E.g. `if`, `for`)
- Logical operators (E.g. `===`,`&&`, `||`,`<`,`<=`,`>`,`>=`, etc.)
- Objects (and `array` of `objects`)
3. Learn how to use more developer tools to study JS code
- Source (i.e. debugger)
- Console (i.e. `console.log`, `console.dir`)
We will continue to observe, analyze and think about this program in terms of:
> What is the STATE?
> What is the SEQUENCE?
> What is the CAUSALITY?
### Part 0: Conceptual Program Overview
Play with the program and observe how it reacts to user interactions.
- _Without_ talking about it in _programming terms_ explain the user observable steps/process of the following three interactions and how the program responds.
- Adding a todo
> User types a todo into the text box and clicks "add" or presses "enter".
> The input is added to the todo list onscreen
- Completing a todo
> User clicks the radio button next to the todo item.
> Todo item is displayed as struck through (crossed out)
- Removing a todo(s)
> If the user clicks the "Remove" button, all items struck through are removed from the list.
Be specific but imagine you are talking to a _non-programmer_. Think about this in terms of observable actions and reactions.
> User puts toast in the toaster. Sets the length of the timer. Pushes the lever to start the toaster. The toast pops out the toaster after the time is completed and goes "DING".
- For each of the interactions above write in _pseudocode_ the steps of how the program for that interaction unfold and results. Pseudocode is semi-formal structure to write out the gist of how your program would work. It uses some keywords but is largely language agnostic. There isn't a single correct way to do it but the following are some rules that can help.
```markdown=
#Adding a todo
WRITE todo item
ADD todo item:
IF user CLICKs "add"
OR user CLICKS any key
{item added to list}
#Completing a todo
CLICK radio button
CROSS OUT todo item
#Removing todos
CLICK (num)Remove
REMOVE completed todos
```
A longer version:
```markdown=
Adding a Todo:
User INPUTS text into text area
User presses ADD button
If user enters a βstringβ then Add button ADDS the new LIST ITEM to the LIST
Completing a Todo
User clicks on LIST ITEM
If the ITEM is struck through then it become NORMAL again
If the ITEM is normal it is struck through
Removing Todos
If any ITEM is STRUCK THROUGH (true) then the Remove button is HIGHLIGHTED RED
If more than 1 ITEM is STRUCK THROUGH then the Remove button displays a COUNT for how many.
If user CLICKS Remove button, ALL STRUCK THROUGH Items are ERASED from SCREEN.
```
- RULES:
- One statement per line
- CAPITALIZE initial _keywords_
- READ, WRITE, IF, ELSE, REPEAT, UNTIL, AND, OR
- Indent to show hierarchy and groups of operation
- Keep statements language independent
```markdown=
# Making toast for a big family
READ loaf of bread
READ slice of loaf
Put slice in toaster
WRITE time to toast
Start the toaster
Cook the toast
READ time
WRITE time by one second less
REPEAT UNTIL time is zero
Remove toast
REPEAT for all slices in loaf
# Serving toast
WRITE number of slices total
READ number of family members
READ toastiness
IF toast is burnt AND (total slices >= number of family members)
throw away toast
decrement slices total
ELSE
serve toast to family member
```
- Using your pseudocode, identify the function(s) in the actual JS code that relate to your pseudocode.
>Add todo item:
`function addTodoItem()`
>
>Complete todo item:
`function toggleComplete(event)`
>Remove todos:
`function removeTodoItem(event)`
- Compare and contrast your pseudocode with the actual code.
>Similarities: our pseudocode linked user actions (eg click "add"; click radio button; click "remove") to their outcomes in the program (eg "item added to ")
>Differences: The actual code breaks the program down into more additional functions, `validateTask` to prevent adding nonexistent tasks to the list by simply pressing enter.
- Explain what similarities and differences you noticed about the instructions / steps / processes in the code vs. your psuedocode.
> The pseudocode was written based on a more visual and user-based (front end) understanding of the program, which means a smaller number of steps and processes are laid out, ignoring how these relate to the DOM and back-end aspects like data retrieval. The actual code is more textual and back-end oriented: there are a lot of steps and processes that the user doesn't see (for example retrieving user input and storing it so it can be printed when they click "add") but are nonetheless essential to the running of the program. The ordering in the code is also completely different. To the front-end user it is seemingly random, as it states certain steps that are "invisible" or taken-for-granted by the user, like `initializeToDos`.
- Manipulate different parts of the code as you see fit. Why did you decide to manipulate that part? What happened? (More structured tinkering to follow.)
>We added an alert to the `if (todosHTML === "")` process so that when the user crosses off everything on their todo list, the program will tell them "Well Done!π". We also discovered in this process that emojis can be simply copy-pasted into JavaScript - although they need to be coded into html.
### Part 1: Variables, Functions, Arrays, and Events
- Explain the `data` variable.
- What does this data (and the data inside) represent conceptually?
>The `data` variable is an array of objects that represents the todo list, with each object representing a task on the list.
- If I wanted to access the second object, how would I do that in code?
>`console.log(data[1]);`
returns the object's data: `{id: 1497141913701, task: 'Eat breakfast', done: false}`
- If I wanted to access the `done` property of the first object, how would I do that?
>`data[0].done`
- Look through the rest of the code where this `data` array is used. When the user does things, am I manipulating the visual display and updating the data to reflect those changes? Or am I manipulating the data and updating the visual display to reflect those changes?
> Both happen in tandem: the user interacts with the visual interface which in turn updates the data, and the program simultaneously acts on data inputs to update the visual display.
- Is this what you would have thought of?
>No, that was one difference we spotted with our pseudo code: we looked at the structure from the USER's perspective, but when we compared our pseudocode with the actual code, and listened to Jin's explanations, we realised that JavaScript makes much sense if we use the data as our entry point and learn to think more like a computer.
- What might be the significance of this program design decision?
The program would be a lot more simple without front end/back end differences between the code and what the user sees, but this is what programming is all about: creating an interface for humans and computers to work together. The front end is the human end and the back end is the computer end.
- What do these lines in my code do?
```javascript=
var todosEl = document.querySelector('#todos');
var inputEl = document.querySelector('input');
var completedEl = document.querySelector('#counter');
```
> they are declaring a variable that is equal to the elements retrieved from the html using `document.querySelector`.
- Why declare these (see above) variables at the Global scope instead of in the functions?
> So that all the functions and code can use them.
- Or not at all... (E.g. `document.querySelector('#todos');`)
>Declaring variables can give the code shorthand to make it easier to read and write.
- The `toggleComplete` function has an event parameter. Inside the function I access `event.currentTarget`. What is the difference between `event.currentTarget` and `event.target` which we used previously?
> event.currentTarget is only available when the event is being handled. current.target is 'always' the element that has the listener on it. event.target identifies the element on which the event occured. **When we are trying to identify multiple elements with one event listener, we use event.currentTarget.**
- Hint 1: You can add a `console.log(event)` etc. inside that function to test the value of `event.target` and `event.currentTarget`.
- Hint 2: When testing, click on a todo to "complete" it. Click on two areas: the `li` as well as the `i` (font icon) element to see the differences.
- Hint 3: You can pass multiple arguments to `console.log()`. I often pass two: first a string label, second the thing I want to log. This will basically make the logs easier to identify if you use `console.log()` a lot.
```javascript=
console.log("SOME LABEL: ", dataToLog);
```
- In the `toggleComplete` function, there is a `event.currentTarget.id`. Is that `id` the same thing as the id property in my todo objects in the `data` array?
- Explain.
> They are the same thing. The `currentTarget.id` specifies the `id` from the todo being clicked on.
- What does `!something` mean? (The exclamation mark) and how is it used in this code when we `toggleComplete`?
> The exclamation mark (β!β) symbol is the logical βnotβ operator. It returns the opposite of `todoData.done`. This toggles the todo's `done` value from `true` to `false` or vice versa.
- Try calling some of the functions directly from the console. Some will work. Some won't.
- Explain what you find.
>I tried typing a Todo into the text entry box and calling `onEnterKey`, but it responded with `"Cannot read properties of undefined (reading 'code')"`. But when I called `addTodoItem()` it added my item to the list and the console returned `undefined`.
- Look at the function declarations in the JS panel.
- _Where_ is each function being called?
>None of the functions are actually _called_ in the JavaScript (except for `initializeTodos`); they are just declared, but these declarations specify the event that will trigger the functions being called. So each function is called when its event listener is triggered by the user (or in some cases from the console).
>However, some functions call other functions when triggered. For example, `updateTodoItems` is called when onclicking `toggleComplete`.
>
- _When_ is each function, actually called?
- What parameter(s) does that function have?
- What is the argument that is passed into the function when it is called?
>
- Use the console (in Chrome devtools) to `console.log()` and `console.dir()` the following. What is the difference between `console.log` and `console.dir` and why is `console.dir` kind of more useful for looking at some kinds of data?
```javascript=
console.log(data);
console.log(todosEl);
console.dir(data);
console.dir(todosEl);
```
> For `(data)`, `console.log` and `console.dir` returned exactly the same thing except that `.dir` specified that `data` is an array.
> For `(todosEl)`, though, `.log` returns the variable's array and data, whereas `.dir` returns a looong list of properties. So `console.dir` is probably more useful when you're looking for specific properties or trying to establish what kind of object something is. It seems`console.log` returns a simple overview whereas `console.dir` is a directory of _all_ of an object's properties.
### Part 2: Objects and Arrays of Objects
- Manipulate the different _properties_ of the _objects_ inside the `data` array.
- Change all todo objects' `done` property to `true`.
- Change some of the task values.
- Run your code and explain how this changes what you see and why.
>When we change all the todo objects to done, we see that all the objects are struck through.
- `console.dir()` the `data` array. Goto the console and _OPEN_ the `> Array(3)` text by clicking on it. Go deeper by opening up the nested objects. Analyze what you see. Then add a new todo through the user interface. `console.dir()` the `data` array again and investigate the insides.
- What is the difference between `data` before and after adding a new todo?
>After adding a new todo, the data array has a new object, with the same mysterious properties listed in the `[[Prototype]]: Object` dropdown menu as the others.
- Run the following code:
```javascript=
data.push({
done: true,
task: "Goto Aikido Lessons",
id: getTimeStamp()
});
console.dir(data);
```
- What did the code above do?
>It added the task "Goto Aikido Lessons" to the `data` array in the console.
- Does our page reflect the changes made? Why or why not? Prove it.
>The page doesn't reflect the changes made, probably because the `updateTodoItems` hasn't been called. When I typed `updateTodoItems()` into the console and pressed enter, the done Aikido todo appeared at the bottom of the list, so I think I was right.
- Does order matter in `Objects`?
>The order of what? The order objects are written in an array will affect the order in which they appear on the screen, but the above (Aikido) code shows that the order in which an object's properties are typed in doesn't matter.
- What is the difference between `Object` keys (E.g. `done`, `task`, `id`) and `Array` indices (E.g. `0`, `1`, `2`)?
- How are they similar?
```javascript=
var myAry = [123, "Code", true];
var myObj = {
id: 123,
task: "Code",
done: true
}
console.log(myAry[1]);
console.log(myObj["task"]);
console.log(myObj.task);
```
>Object keys specify properties of an object, whereas array indices specify the order in which they appear in an array. They're similar in that they're both properties of an object, although the order in which an object appears in an array is less about the object itself and more about where it is positioned in relation to other objects.
- Compare the following in the console:
```javascript=
var element = document.querySelector('ul');
var author = { first: "Mark", last: "Twain" }
var example = {
theAnswer: 42,
student: true,
hobby: "Fishing",
sayHello: function(){
alert("Hello");
},
favNums: [1,2,3],
favAuthor: author
};
console.dir(example);
console.dir(el);
```
- What is an `element` really?
>In this case, the element variable retrieves the unordered list from the html.
- How does our `element` relate in terms of similarities and differences to `example`?
>They both contain at least one object with multiple properties, although `element` is an array whereas `example` is just one object. The element and the example both return `undefined` when typed into the console.
- If I wanted to call the function in the `example` object, how would I do that? Prove it.
> `example.sayHello.function()` doesn't work. We can't figure out how to make it work.
- Try the following code in the console. How does dot notation and bracket notation differ and why would you want to use one or the other?
```javascript=
var x = "username";
var user = {
username: "happyCat"
}
console.log(user.username);
console.log(user["username"]);
console.log(user[x]);
console.log(user.x);
>The [x] was able to be understood by the computer, unlike (x) which returned "undefined", [x] returned the correct value of "Happy Cat" therefore [] annotation should be used.
- Identify various areas where the `.` object notation is used and explain the thing on the left side of the `.` and the thing on the right side of the `.`
- E.g. `document.querySelector()` `document` is... `querySelector` is...
- HINT: There are MANY choices here.
>Document query selector is used to pull information from the HTML. For example, var element = document.querySelector('ul'); pulld the todo list from the HTML.
- In two areas of my code, I use what is called a `filter` function. It's a function that arrays can use like `list.pop()`, `list.push()`.
- How does a filter function work?
>It essentially filters out specific objects from an array based on a specified data filter.
- What is the significance of the function argument that is passed INTO the filter parameters?
>It specifies what kind of data, possessing what properties, it wants to be included in the filtered dataset.
- With regard to the function that is passed into the filter as an argument, that function must `return` a boolean or evaluate to a boolean. What is the purpose of this?
>When performing the filter function, the programme asks "is this the property specified? Yes or no?" and that's how it filters the data, so filter functions need to be phrased in terms of booleans.
- What does the _filter function_ return?
E.g. `var x = list.filter(...); // What was returned to x?`
- CAUTION: NOT the function argument that goes into the filter.
- HINT: If you don't know, can you use console to "test" an idea out?
- Does filtering an array _change_ the original array?
>In the code,
```data.filter(function(todo){
return todo.done === true;
});
```
creates a new value for the arrays, in this case they are all stictly equal to true. The significance of the filter function is that it overrides any previous value. I tested the _filter function_ in the console as
```Javascript=
data.filter(function(todo){
return todo.done =1;
});
and was returned
{
id: 1497141891479,
task: "Wake up",
done: 1
},
```
therefore this changed the value of the done to 1 which does not make any sense logically. The value of done is to define the final state of the object therefore it can only be defined through true or false.
### Part 3 Control Structures
- I use the `if` statement in several places in this code. Explain why a conditional is necessary in:
- `updateTodoItems`
>The conditional is necessary here because the program responds differently based on whether todos are done or not.
- `updateRemoveButton`
>The program responds differently based on whether or not there are done todo items to remove.
- `onEnterKey`
>The program responds differently based on whether or not there is a string in the input field.
- `validateTask`
>The program responds differently based on whether or not there is a string in the input field.
- `addTodoItem`
>The program responds differently based on whether or not there is a string in the input field.
- `getTodoData`
>The program responds differently based on whether an id matches the id it's looking for.
- HINT: You might want to `console.log` the boolean condition where you see the `if` statements to understand what condition we are evaluating.
```javascript=
if (booleanCondition) {
...
}
console.log(booleanCondition);
```
- Comment on how the boolean condition works as there are many different examples.
>If the condition of the object in question matches that which is specified, the progam takes a specific actions.
- In this code, there are two kinds of `for` loops. The more traditional that looks like:
```javascript=
for (var i=0; i < list.length; i++) {
// CODE
}
```
and a `for of` loop that looks like:
```javascript=
for (item of list) {
// CODE
}
```
- How does a `for of` loop work?
- What does the `item` represent? (It can be named anything: `x`, `item`, `thing` etc.)
>>the item represents any of the items in an array /list /arguments etc that the for loop iterates one by one. executing a function(s) for the value of property.
- Why are `for of` loops convenient compared to the traditional `for`?
>> Traditional for loops are more bulky to write, for of loops are like short cuts.
- For what purpose(s) do I employ a `for` or `for of` loop in this program?
> for loop: for finding the list item by id
for of : determining if todo elements in the list are ticked complete. But I couldn't find how we use it elsewhere in the code.
I think it is because in for loop we mention specifiaclly initial expression, condition expression and increment expression, and we want to make an operation on two of them. But I am not sure if we can't write this with for of, the statement returns itself, or null, which kind of confued me.
- On Facebook or Pinterest, or Twitter, how does a loop through data relate to the display of content?
> They all output the same template, so the visual always is the same, except the code integrates user input like text, video, etc into the html.
### Part 3 Specific Routines
- Take a look at the `updateTodoItems`. Comment it out and replace it with this alternate, but functionally identical version. How does this function work and how do they relate / differ?
> I thought this was more readable for me. But I lost the i elements, although they are in the code, they no longer appear on html.
This version creates the variable, the list first appears empty in full page mode, as soon as I enter a new item though, all the other 3 appear. So I presume, changing the place of `nothing to do` caused this but why? As it neither says nothing to do in the beginning.
```javscript=
function updateTodoItems() {
todosEl.innerHTML = "";
if (!data.length) {
var liElement = document.createElement('li');
liElement.innerText = "Nothing todo...";
todosEl.appendChild(liElement);
} else {
for (todo of data) {
var liElement = document.createElement('li');
var iElement = document.createElement('i');
liElement.id = todo.id;
liElement.onclick = toggleComplete;
if (todo.done) {
liElement.className = "complete";
iElement.className = "fa fa-check-circle-o";
} else {
iElement.className = "fa fa-circle-o";
}
liElement.appendChild(iElement);
liElement.innerText = todo.task;
todosEl.appendChild(liElement);
}
}
updateRemoveBtn();
}
```
- Take a look at the helper function `getTimeStamp`. This function will return a number, in milliseconds, the current time stamp since January 1, 1970.
- I call this when I create new todo items, what are some ideas as to why I might be using a timestamp for todo `ids`?
> As explained in the class, timestamp is used so that we have unique id's and we don't have to create them, we are using a built-in method to generate these unique ids.
- Take a look at the incomplete functions `markAllComplete` and `updateItemsLeft`.
- Can you complete these and add the functionality to this app?
``` html=
<button onclick="markAllComplete()"><span id="markComplete"></span>Mark All Complete</button>
</div>
```
```javscript=
function markAllComplete() {
var markAllHTML = "";
data.splice(0,data.length)
updateTodoItems();
}
```
>> this works but I am not sure if that is what Jin wanted, I am not calling this function somewhere else in the code.
``` html=
<div class = "updateItems" >
<h3 id="itemsRemaining"> You have <span id= "remains"> </span> tasks left </h3>
</div>
</div>
```
```javscript=
function updateItemsLeft() {
var remainingEl = document.querySelector('#remains');
//var remainingHTML = "";
var remainingItems = data.filter(function(todo){
return todo.done !=== true;
});
remainingEl.textContent = remainingItems.length;
//remaingEl.innerHTML = remainingHTML;
}
```
>doesn't work and also breaks the whole code, list items dissappear, can't add new todo.
>> Expected an identifier and instead saw '{a}'. Unrecoverable syntax error.
### Part 4 Debugging, Tools
Using the Chrome debugger (source) tool create breakpoints and watch the program execute line by line, part by part. Experience how this tool can give you insight into your program's _STATE_, _SEQUENCE_, _CAUSALITY_.
#### Chrome Debugger
- Set breakpoints at the following locations of your program
- `function initializeTodos`
- `function onEnterKey`
- `function addTodoItem`
- `function toggleComplete`
- Use the `Step over the next function call` feature to watch how the program pauses during the _SEQUENCE_ of its routines.
- What is the difference between `Step over` and `Step into` and how does this help you understand programs?
> `Step over` takes us to the next function call, while `step into` takes us inside of the called function. The former is useful to help us track the order in which functions are called, meanwhile the latter is more useful for analysing how a particular function impacts the overall script.
- Use `Step into` until you've reached the line `var inputEl = document.querySelector('input');`. Should be highlighted in blue.
- Highlight the variable `todosEl` on the line before it and `right click` on it. Select _Evaluate in console_.
- What does the console print?
> `<ul id="todos">
<!-- ITEMS HERE -->
</ul>`
- Highlight the variable `inputEl` on this highlighted blue line.
- Why does the console say `inputEl` is undefined?
>Perhaps, since we stopped on this line, definition of this variable has not been executed yet. I stepped into the next line of code, highlighted `inputEl` and evaluated it in the console. I got this: `<input type="text" onkeypress="onEnterKey(event)">` Eureka!
- When you step through your code, does the blue line represent code that is about to be executed or code that has already executed? How do you know?
> Code that's about to be executed, because I only see the changes being made onscreen after I've moved onto the next line. Also, as per the last question, a variable is only defined when we move past it!
- What do you predict would be the console value of the variable `completedEl` on the next line if you _Evaluate to console_ at this point?
> Until we step into the line after it, the variable will remain undefined!
- Watch how debugger annotates your source code with the updated _state_ of different variables as your program progresses.
- How does the debugger behave when you enter a loop in your program?
- How does the debugger behave when you reach the a `filter` function call?
- What does filter do and how does it work?
>Apologies, I cannot see annotations in debugger...
### Part X: Putting all together
**Explain the program line by line with sufficient details, part by part.**
:::success
- Line by line
- Part by part
- Be sure to copy blocks of code into this markdown using code formatting/fences as references to your explanations.
- For repetitive code, you can explain how a line works then summarize how it would work for the rest.
:::
**Relevant HTML:**
- Lines 11-13: the `<ul></ul>` tags are used to create an unordered list, which demarcates where the todo list will go. It's nominally empty, but items will be parsed into it using the JavaScript code.
- Line 15 creates a `<div>` for controls, which ends in line 19.
- Line 16 sets up a text input box with an event listener (`onkeypress`) for if the user types into the box.
- Line 17 creates an "Add" button with the event listener `onclick`, which will trigger the JavaScript function `addTodoItem` when the user clicks the button.
- Line 18 creates a "Remove" button with the event listener `onlcick`, which will trigger the JavaScript function `removeTodoItem` when the user clicks the button. The button also contains a span: `<span id="counter"></span>` which counts how many complete todos there are to remove.
**JavaScript:**
- Lines 2-18 establish the the variable "data", an array of objects that serve as the initial items on the todo list. Each item has an `id` in the form of a number, a `task` property in the form of a string (this is the actual todo task that is read by the human user) and a`done` property whose value is a `true` or `false` boolean.
- Lines 21-23 establish three variables, and use `document.querySelector` to assign values to them based on data from the html code. The variable`todosEl` corresponds with the unordered list with the id `todos` in the HTML;`inputEl` corresponds with the text from the input field on the front end (the text box where the user types in their todo); and `completedEl` corresponds with the span with the id `counter` in the HTML.
- Lines 25-27 declare the function `initializeToDos()`, which calls the function `updateTodoItems()`.
- Lines 29-49 declare the function `updateTodoItems()`:
- Line 29 declares the function.
- Line 30 establishes the variable `todosHTML` as a blank string (`""`).
- Line 31, `(for todo of data)` is essentially saying "for each object in the `data` array":
- Line 32, `if (todo.done)` is saying "if the object's 'done' value is true..."
- Lines 33 and 34 stipulate the program must then add the object to the `todosHTML` array (`todosHTML +=`) with the class "fa fa-check-circle-o", which effectively applies styles to the todo item to check the circular box next to it and strike through its text; in other words, marks it complete in a way that's readable for the user.
- Lines 35-37 stipulate `else` (if the todo is not done), add the todo to the list with the class "fa fa-circle-o", whose styles display the todo as not done (not checked or struck through) to the user.
- Lines 33 and 36 also each add an `onclick` event listener to the Todo which executes the function `toggleComplete` when the user clicks on the todo.
- Line 40 ensures that every todo task will be added to the `todosHTML` list.
- Line 41 adds the list closing tag `</li>` to the `todosHTML` string.
- Line 43 stipulates that if `todosHTML` is still an empty string (if there are no items on the todo list), then the program should display the text "Nothing todo...". Note that it doesn't have the class "fa fa-check-circle-o", so this message doesn't display as a todo item with a box to tick.
- In line 45, we have added an instruction that has the program display an alert "well done! π" if the todo list is empty.
- Line 47 assigns the value `todosHTML` to the `todosEl` variable's `innerHTML` content (its HTML content).
- Line 48 calls the function `updateRemoveBtn` and line 49 closes the function declaration.
- Lines 51-63 declare the function `updateRemoveBtn`.
- Line 51 creates a variable `completedTodos`, and assigns a value to it that is the result of applying a filter to the `data` array that selects all the todos whose `done` property value is `true`.
- Line 56 changes the value of `completedEl`'s text content to the length of the `completedTodos` array (the number of completed todos).
- Lines 58-59 stipulate that if the length of the `completedTodos` array is not nonexistent (in other words, if there are completed todos), then the `completedEl parentElement` will not be disabled (the "Remove" button will be active).
- Lines 60-61 stipulate that if there is no `completedTodos` array (if there is no `completedEl parentElement`), then the "Remove" button will be disabled. This means the program won't make the "Remove" button clickable unless there are actually completed todos to remove.
- Lines 65-69 declare the function `onEnterKey` with the argument `event`.
- Line 66: `if (event.code === "Enter")` means "if the event is the user pressing the 'Enter' key". If this happens, then the function `addTodoItem` will be called, per line 67.
- Lines 71-77 declare the function `validateTask`.
- Line 72 stipulates that if the `task` property of a todo is not an empty string, (in human terms, if the input box has text in it), return `true` (line 73), `else` (line 74) return `false`(line 75).
- Effectively, this function stops blank todo items from being created whenever the user clicks "add" without typing anything in.
- Lines 79-96 declare the function `addTodoItem`.
- Line 80 stipulates that if the `validateTask` function does not (`!`) return an `inputEl.value` (in other words, if the `validateTask` function shows that the input field is empty), return/do nothing (line 81), else...
- Line 84 creates the variable `newTodo`.
- Line 85 assigns its `id` as the value returned by the function `getTimeStamp`, which returns the number of seconds or miliseconds elapsed since midnight on 1 January, 1970. This effectively assigns the `newTodo` a unique `id`.
- Line 88 designates the variable's `task` value to be the value of the `inputEl`: i.e. whatever the user has typed into the text input box.
- Line 89 assigns the variable a `done` value of `false`.
- Line 91 pushes the `newTodo` variable into the `data` array, effectively adding the content of the front-end text input field onto the todo list as a new item.
- Line 93 calls the function `updateTodoItems`.
- Line 94 calls the function `resetInput`.
- On line 96, `debugger;` effectively sets a break point in the code.
- Lines 98-103 declare the function `toggleComplete` with the argument `event`.
- Line 99 creates a variable `todoID` and assigns it a value corresponding with the `id` of the selected `todo` (the `todo` being clicked on, designated by `currentTarget`: the element whose event listener triggered the execution of this function).
- Line 100 creates a variable `todoData` and assigns it the return of the function `getTodoData` when the variable `todoID` is parsed into it.
- Line 101: `todoData.done = !todoData.done;` sets the `todoData` variable's `done` property to the opposite of what it is, effectively toggling the todo item from "done" to "not done" or vice versa.
- Line 102 calls the function `updateTodoItems`.
- Lines 105-111 declare the function `removeTodoItem` with the argument `event`.
- Line 106 creates the variable `incompleteTodos` and assigns it the value corresponding to the result of the `filter` function filtering out any todo whose `done` property is `false` (line 107).
- Line 109 reassigns the `data` value to be equal to this filtered list of `incompleteTodos`, so that the todo list now only include incomplete todos (the complete todos have been removed).
- Line 110 calls the function `updateTodoItems`.
- Lines 113-115 declare the function `resetInput`.
- Line 114 reassigns the `inputEl` variables `value` to `""`: an empty string; a blank input box.
- Lines 117-133 declare the function `getTodoData` with the argument `id`. This function finds the todo data corresponding with the id of the event listener of the todo that is clicked on by the user to toggle it done or not done.
- Line 118 creates a variable `todoFound`.
- Lines 120-126 set up a loop that looks for the data corresponding with the clicked-on `id`.
- Line 120 states the parameters: starting with the first object, continuing one by one for the length of the `data` array.
- Lines 121-122 stipulate that if the object's `id` mathes the `id` passed into the function, its properties will be assigned to the variable `todoFound`.
- Line 124 inserts a break so that the loop will stop running once the relevant todo has been found (once the above action has been executed).
- Lines 128-131 stipulate that if `todoFound` has no value; if it is not found; the program returns `null`.
- Once all of these functions have been declared, the program actually starts, in line 159, by calling the function `initializeTodos`. From there, it runs by responding to user input, as stated above.
- Lines 163-166 declare some variables as follows, the purpose of which I am unsure:
```Javascript=
var x = "username";
var user = {
username: "happyCat"
}
```
**Make it yours (group's)**
:::success
- Try to extend this program to do something cool, as a group, your own original idea(s).
- What is something that a Todo list or todo list user might benefit from?
:::
We moved the `counter` span in the html code to the other side of the "remove" button, so that it reads "Remove 1" instead of "1 Remove". This makes it more grammatically human.