# Javascript Part II
### Part 0: Conceptual Program Overview
**- Without talking about it in programming terms explain the user observable steps/process of the following three interactions and how the program responds.**
(1) Adding a todo: User select and click on the text entry box. Write down a todo content in the box. Click on the add buttion. And then a new todo (with unchecked button) will appeared.
(2) Completing a todo: User click on the checkbox of the todo that they have completed. And it the style and font will changed. The remove button will turn read with a number in the front indicating the number of todo that the user have completed.
(3) Removing a todo: User click on the remove button. All of the todos that have been marked as completed will delete. And the print section will show the words "Nothing todo...".
* **For each of the interactions above write in _pseudocode_ the steps of how the program for that interaction unfold and results.**
:::success
```Pseudocode=
# Adding a todo
user CLICKS on the text entry box
user TYPES in the box
user CLICKS the add button
Then the new todo item will APPEARED in the list
# Completing a todo
user CLICKS the checkbox button next to a todo item
the todo will be crossed-out
the remove button will TURN red
ADD number of todo that have been completed infront
# Removing a todo
user CLICKS the remove button
If the todo have been CHECKED
item will be DELECTED from the list
Else
nothing will happened
If all the todo have been COMPLETED and REMOVED
"Nothing todo…" will APPEARED on the screen
```
:::
- Using your pseudocode, identify the function(s) in the actual JS code that relate to your pseudocode.
:::success
Similarities: They are have state, sequence and causality.
Differences: The pseudocode is more logical in the computing way.
:::
- 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.)
---
### Part 1: Variables, Functions, Arrays, and Events
- Explain the `data` variable.
- What does this data (and the data inside) represent conceptually?
:::success
`data` variable represent a array of object which will appear when the user first load the page. And they have three properties: id, task and done.
:::
- If I wanted to access the second object, how would I do that in code?
:::success
`var secondObject = data [1];`
:::
- If I wanted to access the `done` property of the first object, how would I do that?
:::success
`var selectProperty = 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?
:::success
You are manipulating the data and updating the visual display to reflect those changes.
:::
- Is this what you would have thought of? What might be the significance of this program design decision?
:::success
This decision allows the visual display changed along with the users'data.
:::
- What do these lines in my code do?
```javascript=
var todosEl = document.querySelector('#todos');
var inputEl = document.querySelector('input');
var completedEl = document.querySelector('#counter');
```
:::success
`var todosEl = document.querySelector('#todos');` select the list that have a id "todo".
`var inputEl = document.querySelector('input');` select the input that user entered
`var completedEl = document.querySelector('#counter');` select whether user's remove action
:::
- Why declare these (see above) variables at the Global scope instead of in the functions?
:::success
Variables are called in across a number of functions, so it need to be called in the global section.
:::
- 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?
:::success
`event.target` is what triggered the event at the first place such as user clicked. `event.currentTarget` is the current or last element that resulted from the chain of events.
:::
- 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.
:::success
Not the same. `event.currentTarget.id` is a string. However the `id` property the `data` array is a number.
:::
- What does `!something` mean? (The exclamation mark) and how is it used in this code when we `toggleComplete`?
:::success
`!` means not. So in the code
`todoData.done = !todoData.done`
if it was true it would now be false.
:::
- Try calling some of the functions directly from the console. Some will work. Some won't.
- Explain what you find.
:::success
:::
- Look at the function declarations in the `todos.js` file.
- _Where_ is each function being called?
:::success
4 of the functions are called by the user when they interact with the webpage.
`onEnterKey(event)`is called when the user press the enter key.
`addTodoItem()` is called when the user clicks the add button.
`removeTodoItem()`is called when the user clicks remove button.
:::
- _When_ is each function, actually called?
:::success
When the user interact with the web.
:::
- What parameter(s) does that function have?
:::success
event
:::
- What is the argument that is passed into the function when it is called?
:::success
The key that user pressed.
:::
- 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);
```
:::success
`.log `prints out the actual code.
`.dir` prints out the type of code.
:::
---
### 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.
:::success
All of the todo objects were shown as completed.
The items in the TODO List X changed with the new task values.
Because the `done` property indicated whether the todo is complete or not. the `task` property indicates the content of the task.
:::
- `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?
:::success
The length of the `data` array became 4.
:::
- Run the following code:
- What did the code above do?
- Does our page reflect the changes made? Why or why not? Prove it.
- Does order matter in `Objects`?
:::success
Add a new object in the `data` array.
Yes.
No, it doesn't matter.
:::
- What is the difference between `Object` keys (E.g. `done`, `task`, `id`) and `Array` indices (E.g. `0`, `1`, `2`)?
:::success
By using `ojbect`, the order of element doesn't matter.
:::
- How are they similar?
:::success
Both of them can consist various of element and data. And can be retrived later.
:::
- 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?
:::success
The dot notation is used for value and the bracket notation is used for name.
:::
- 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.
:::success
`completedTodos.length`: `completedTodos` is a variable. `length` is its length property.
:::
- 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?
:::success
The `filter()` method creates a new array with all elements that pass the test implemented by the provided function.
:::
- What is the significance of the function argument that is passed INTO the filter parameters?
:::success
:::
- 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?
:::success
:::
- 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?
:::success
A new array with all elements that meet the requirement of the new filter function.
:::
- Does filtering an array _change_ the original array?
:::success
No.
:::
## Part 3 Control Structures
I use the if statement in several places in this code. Explain why a conditional is necessary in:
updateTodoItems
updateRemoveButton
onEnterKey
validateTask
addTodoItem
getTodoData
HINT: You might want to console.log the boolean condition where you see the if statements to understand what condition we are evaluating.
if (booleanCondition) {
...
}
-Conditional is needed since the function will possibly be changed.
console.log(booleanCondition);
Comment on how the boolean condition works as there are many different examples.
In this code, there are two kinds of for loops. The more traditional that looks like:
for (var i=0; i < list.length; i++) {
// CODE
}
and a for of loop that looks like:
for (item of list) {
// CODE
}
How does a for of loop work?
-for/of - loops through the values of an iterable object
-for - loops through a block of code a number of times
What does the item represent? (It can be named anything: x, item, thing etc.)
-Objects are variables too. But objects can contain many values.
Why are for of loops convenient compared to the traditional for?
For what purpose(s) do I employ a for or for of loop in this program?
-In general, enhanced for loop is much more easy to use and less error prone than for loop, where you need to manage the steps manually. At the same time, for loop is much more powerful because you get the opportunity to control over looping process.
On Facebook or Pinterest, or Twitter, how does a loop through data relate to the display of content?
-The JavaScript for/of statement loops through the values of an iterable objects
for/of lets you loop over data structures that are iterable such as Arrays, Strings, Maps, NodeLists, and more.
---
### 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?
```javascript=
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?
:::success
The function works similar with two versions. The updated one does not have the radio button compared to the previous one. The updated one also used todoEl.innerHTML instead of var todosHTML, and used if else statement first, then for loop then if else, instead of the for loop and have the if else inside. The previous one seems more simplified.
:::
* Take a look at the incomplete functions markAllComplete and updateItemsLeft.
* Can you complete these and add the functionality to this app?
---
### 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.
Use the Step into 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?
Use Step into until you’ve reached the line var inputEl = document.querySelector('input');. Should be highlighted in blue.
-Step over: The step over also executes one line of code at a time. The difference between Step Over and Step Into occurs when your code calls to other procedure. Step over displays only one line of code in the current procedure.
step into: If line of code is call to another procedure will be displayed. To continue stepping through your program execution, continue choosing the step into command.
Highlight the variable todosEl on the line before it and right click on it. Select Evaluate in console.
What does the console print?
-the console printed todo items and checked elements are highlighted.
Highlight the variable inputEl on this highlighted blue line.
Why does the console say inputEl is undefined?
-Because the input elements are not printed.
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?
-the blue line respresnts code that is about to be executed.
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?
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?
-An automatic debugger is a powerful tool for aiding our reasoning process during debugging. It can be invaluable in those frustrating cases where the program crashes without any output at all, as the debugger will usually take us right to the location where the crash occurred.
---
### Part X: Putting all together
* Explain the program line by line with sufficient details, part by part.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.
:::success
2-23 database with its id and attributes
:::
```javascript=
var data = [
{
id: 1497141891479,
task: "Wake up",
done: false
},
{
id: 1497141913701,
task: "Eat breakfast",
done: false
},
{
id: 1497141937545,
task: "Learn code",
done: true
}
];
// Important Elements - Cached as variables
var todosEl = document.querySelector('#todos');
var inputEl = document.querySelector('input');
var completedEl = document.querySelector('#counter');
```
:::success
27-29 Separate each part and save them as variables
31-33 initialization, default setting
35-54 Reading the data from the data sets and output them one by one
36 initialize the inserted html
37 for loop to iterate each data
32 if data’s attribute “done” is True
33-34 add it as complete class (the one has been chosen) and link the click event with toggleComplete Function
36-37 if data’s attribute “done” is False, add it without complete class and link the click event with toggleComplete Function
40 Add the data’s task name in html
41 change to another line
43-44 if there is no data to add, print Nothing to do…
46 add what we have done above into HTML
47 Call updateRemoveBtn function
50-52 Filter the data with attribute “done” is True. Save these data into completedTodos
:::
```javascript=
function initializeTodos() {
updateTodoItems();
}
function updateTodoItems() {
var todosHTML = "";
for (todo of data) {
if (todo.done) {
todosHTML += `<li id="${ todo.id }" class="complete" onclick="toggleComplete(event)">`;
todosHTML += `<i class="fa fa-check-circle-o"></i>`; // Font-awesome
} else {
todosHTML += `<li id="${ todo.id }" onclick="toggleComplete(event)">`;
todosHTML += `<i class="fa fa-circle-o"></i>`; // Font-awesome
}
todosHTML += `${ todo.task }`;
todosHTML += `</li>`;
}
if (todosHTML === "") {
todosHTML = "<li>Nothing todo...</li>";
}
todosEl.innerHTML = todosHTML;
updateRemoveBtn();
}
function updateRemoveBtn() {
var completedTodos = data.filter(function(todo){
return todo.done === true;
});
```
:::success
55 count how many data has been saved
57-60 If any data has been saved, the button will be red and can be click, otherwise it will be grey and cannot be click
64-66 If we press the “Enter” Key, we will call addTodoItem
70-74 check if the input exist, if not retune false
79-80 call 70-74. If it returns false (no input), do nothing
:::
```javascript=
completedEl.textContent = completedTodos.length;
if (completedTodos.length) {
completedEl.parentElement.disabled = false;
} else {
completedEl.parentElement.disabled = true;
}
}
function onEnterKey(event) {
if (event.code === "Enter") {
addTodoItem();
}
}
function validateTask(task) {
if (task !== "") {
return true;
} else {
return false;
}
}
function addTodoItem() {
if (!validateTask(inputEl.value)) {
return;
}
```
:::success
83-85 set a new data and set timestamp as its id (timestamp) timestamp
87-88 Set the input as it’s task name and mark it as incomplete
90 put this data into database
92 repeat 36-47
93 clean the input cell
96-100 toggleComplete Event, if someone click any row from the list
97 Read the ID of that row
98 Read the data according to that id
99 mark complete as incomplete, incomplete as complete
:::
```javascript=
var newTodo = {
id: getTimeStamp()
};
newTodo.task = inputEl.value;
newTodo.done = false;
data.push(newTodo);
updateTodoItems();
resetInput();
}
function toggleComplete(event) {
var todoID = parseInt(event.currentTarget.id);
var todoData = getTodoData(todoID);
todoData.done = !todoData.done;
updateTodoItems();
}
```
:::success
100 repeat 36-47
:::
```javascript=
updateTodoItems();
```
:::success
103-108 if someone click the red button
104-106 Filter the data with attribute “done” is False. Save these data into incompletedTodos
107 replace the database with incompletedTodos (delete the complete data)
108 repeat 36-47
115-113 clean the input cell
115-126 Given an id as input, read each data from database, if id matches, return this piece of id. Otherwise return null.
134-135 read time stamp
:::
```javascript=
function removeTodoItem(event) {
var incompleteTodos = data.filter(function(todo){
return todo.done === false;
});
data = incompleteTodos;
updateTodoItems();
}
function resetInput() {
inputEl.value = "";
}
function getTodoData(id) {
var todoFound;
for (var i=0; i < data.length; i++) {
if (data[i].id === id) {
todoFound = data[i];
// var indexAt = i;
break;
}
}
if (todoFound) {
return todoFound;
} else {
return null;
}
}
// HELPER FUNCTION
function getTimeStamp() {
return Date.now(); // this returns a timestamp in milliseconds since 1970.
}
```
* Make it yours (group’s)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?