Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Keith Corona
9,553 PointsInteractive webpages with JS: error code in JS Console
Hello All,
I have completed the interactive webpages w/JS course, but I am having an issue with my code. When I open the JS console, I immediately get an Uncaught TypeError: Cannot read property "querySelector" of undefined - bindTaskEvent @app.js:118 and (anonymous function) @app.js:149 .
I don't know what the errors are.
JS
//User interaction doesn't provide desired results
//Solution: add interactivity so the user can manage daily tasks
var taskInput = document.getElementById("new-task"); //new-task
var addButton = document.getElementsByTagName("button")[0]; //first button
var incompleteTasksHolder = document.getElementById("incomplete-tasks"); //incomplete-tasks
var completedTasksHolder = document.getElementById("completed-tasks"); //completed-tasks
//New task list item
var createNewTaskElement = function(taskString) {
//Create list item
var listItem = document.createElement("li");
//input checkbox
var checkBox = document.createElement("input"); //checkbox
//label
var label = document.createElement("label");
//input (text)
var editInput = document.createElement("label"); //text
//button.edit
var editButton = document.createElement("button");
//button.delete
var deleteButton = document.createElement("button");
//Each element needs modifying
checkBox.type = "checkbox";
editInput.type = "text";
editButton.innerText = "Edit";
editButton.className = "edit";
deleteButton.innerText = "Delete";
deleteButton.className = "delete";
label.innerText = taskString;
//Each element needs appending
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
//Add a new task
var addTask = function() {
console.log("Add task..");
//Create a list item with the text from #new-task:
var listItem = createNewTaskElement(taskInput.value);
//append listitem to incompletetaskholder
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
taskInput.value = "";
}
//Edit an existing task
var editTask = function() {
console.log("Edit task..");
var listItem = this.parentNode;
var editInput = listItem.querySelector("input[type=text]");
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
//If class of parent is .editMode
if(containsClass) {
//Switch from editMode
//label text become input's value
label.innerText = editInput.value;
} else {
//Switch to .editMode
//input value becomes the label's text
editInput.value = label.innerText;
}
//toggle .editMode on the parent
listItem.classList.toggle("editMode");
}
//Delete an existing task
var deleteTask = function() {
console.log("Delete task..");
var listItem = this.parentNode;
var ul = listItem.parentNode;
//Remove parent list item from the ul
ul.removeChild(listItem);
}
//Mark a task as complete
var taskCompleted = function() {
console.log("Task complete..");
//When checkbox checked
//Append the task li to the #completed-tasks
var listItem = this.parentNode
completedTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskIncomplete);
}
//Mark a task as incomplete
var taskIncomplete = function() {
console.log("task incomplete..");
//When checkbox unchecked
//Append the task li to #incomplete-tasks
var listItem = this.parentNode
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
console.log("Bind list item events");
//select taskListItem's children
var checkBox = taskListItem.querySelector("input[type=checkbox]");
var editButton = taskListItem.querySelector("button.edit");
var deleteButton = taskListItem.querySelector("button.delete");
//bind the editTask to edit button
editButton.onclick = editTask;
//bind deleteTask to the delete button
deleteButton.onclick = deleteTask;
//bind checkBoxEventHandler to checkbox
checkBox.onchange = checkBoxEventHandler;
}
var ajaxRequest = function() {
console.log("Ajax request");
}
//Set click handler to the addTask function
addButton.addEventListener("click", addTask);
addButton.addEventListener("click", ajaxRequest)
//Cycle over incompleteTasksHolder ul items
for (var i = 0; i < incompleteTasksHolder.children.length; i++) {
//bind events to list item's children (taskCompleted)
bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}
//Cycle over completedTasksHolder ul items
for (var i = 0; i < incompleteTasksHolder.children.length; i++) {
//bind events to list item's children (taskIncomplete)
bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}
and HTML
<!DOCTYPE html>
<html>
<head>
<title>Todo App</title>
<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8">
</head>
<body>
<div class="container">
<p>
<label for="new-task">Add Item</label><input id="new-task" type="text"><button>Add</button>
</p>
<h3>Todo</h3>
<ul id="incomplete-tasks">
<li><input type="checkbox"><label>Pay Bills</label><input type="text"><button class="edit">Edit</button><button class="delete">Delete</button></li>
<li class="editMode"><input type="checkbox"><label>Go Shopping</label><input type="text" value="Go Shopping"><button class="edit">Edit</button><button class="delete">Delete</button></li>
</ul>
<h3>Completed</h3>
<ul id="completed-tasks">
<li><input type="checkbox" checked><label>See the Doctor</label><input type="text"><button class="edit">Edit</button><button class="delete">Delete</button></li>
</ul>
</div>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
2 Answers

Steven Parker
241,488 PointsUsing a fork of your workspace, I still did not see the error you mention in the console just from opening it.
However, I did notice a couple of issues:
- on line 20, you create a "label" element, but the comment on line 19 suggests it should be "input" instead
- on line 147, your iteration limit is based on incompleteTasksHolder but you are binding completedTasksHolder
That second issue certainly could be the cause of the error you mentioned, after performing some operations on the page.

Steven Parker
241,488 PointsI didn't see any errors. It made me wonder if something that wasn't included (like the CSS) might make a difference.
If you are using workspaces, you can make a snapshot of your workspace to share everything at once.

Keith Corona
9,553 PointsHi Steven,
Here is a snapshot. https://w.trhou.se/lpe3d4kodd
I didn't mess with the css as it was not needed for this project, but perhaps I clicked on it at one time or another and typed something in. I couldn't catch anything. Thank you
Keith Corona
9,553 PointsKeith Corona
9,553 PointsThank you, Steven. I am not sure if just my version of Chrome was showing those errors or what, but now everything is ok. I also made the changes you suggested and no errors appeared.