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

JavaScript Interactive Web Pages with JavaScript Traversing and Manipulating the DOM with JavaScript Perform: Traversing Elements with querySelector

Eric Welch
Eric Welch
20,754 Points

console error: ReferenceError: taskListItem is not defined

Basically I'm asking if I missed something in the instructions. I did a search of my workspace code and only returned taskListItem in this function:

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");

...}

So taskListItem is a variable that should have been declared globally? Am I missing something?

Eric Welch
Eric Welch
20,754 Points

my entire app.js file:

//Problem: UX doesn't provide results.
// Solution: add interactivity

var taskInput = document.getElementById("new-task"); //new task
var addButton = document.getElementById("add_button"); //first button
var incompleteTasksHolder = document.getElementById("incomplete-tasks"); //incomplete-tasks
var completedTasksHolder = document.getElementById("completed-tasks"); //completed-tasks

//Add new task
var addTask = function() {
  console.log("Add task...");
  //  when button is pressed
  //  create a new list item with the text from #new-task:
  //    input (checkbox)
  //    label
  //    input (text)
  //    button.edit
  //    button.delete
  //    each elements, need to be modified and appended
}

//edit existing task
var editTask = function() {
  console.log("edit task...");
  //  When edit button is pressed,
  //    if the parent has class .editMode
  //     switch from edit mode
  //     label text become input value
  //    else
  //      switch to .editMode
  //      input value becomes the label's text

//  toggle edit mode
} 

//delete existing task
var deleteTask = function() {
  console.log("delete task...");
  //  when delete button is pressed 
  //    remove parent list item from ul
}

//mark task complete
var taskCompleted = function() {
  console.log("complete task...");
  //  when checkbox is chcked
  //    append list item to #completed-tasks
}

//mark task incomplete
var taskIncomplete = function() {
  console.log("incomplete task...");
  //  when the checkbox is unchecked
  //    append the task list item to the #incomplete-tasks
}

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 editTask to edit button
  editButton.onclick = editTask;

  //    bind deleteTask to delete button
  deleteButton.onclick = deleteTask;

  //    bind checkBoxEventHandler to checkbox
  checkBox.onchange = checkBoxEventHandler;
}


//set the click handler to the addTask function
addButton.onclick = addTask;

// cycle over incompleteTaskHolder ul list item
for(var i = 0; i < incompleteTasksHolder.children.length; i++) {
  //  bind events to list item's children (task completed)
  bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}
// cycle over completeTaskHolder ul list item
for(var i = 0; i < incompleteTasksHolder.children.length; i++) {
  //    bind events to list item's children (task incomplete)
  bindTaskEvents(completedTasksHolder.children[i], taskIncomplete); 
}

1 Answer

Steven Parker
Steven Parker
231,248 Points

:point_right: Your last loop is using the wrong limit.

Take a look at the last loop of the program:

for (var i = 0; i < incompleteTasksHolder.children.length; i++) {
  //    bind events to list item's children (task incomplete)
  bindTaskEvents(completedTasksHolder.children[i], taskIncomplete); 
}

Notice that the loop is passing the children of completedTasksHolder to bindTaskEvents one at a time, but the loop itself is using the number of children of incompleteTasksHolder as it's limit. So unless both lists have exactly the same number of children, this loop will run too few or too many (where some will be "not defined") times.

Eric Welch
Eric Welch
20,754 Points

Thanks, straightened out that loop and things work