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

Brian Edelman
Brian Edelman
2,293 Points

Uncaught TypeError: Cannot read property 'querySelector' of undefined in bindTaskEvents

//Problem: 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"); //ul "#incomplete-tasks"
var completedTasksHolder = document.getElementById("completed-tasks"); //ul "#completed-tasks"

//Add a new task

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


}


//edit an existing task

var editTask = function() {
    console.log("edit Task...");
    // when the edit button is pressed
    //if class of the parent is .editMode
      //switch from .editMode 
        //label text become the input's value
      //else
        //switch to .editMode
        //input value becomes the label's text

       //toggle .editMode on the parent


}


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





//mark a task as complete
var taskCompleted = function() {
    console.log("complete Task...");
  //when the checkbox is checked 
    //append the task list item to the completed-tasks
}


//Mark a task as incomplete
var taskIncomplete = function() {
    console.log("incomplete Task...");
  //when the bheckbox is checked
    //append the task list item to the incomplete-tasks
}


var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
  console.log("Bind list item events");
   //select it'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 incompleteTasksHolder ul list items
for(var i = 0; i < incompleteTasksHolder.children.length; i++) {

  //bind events to list items children (tasksIncompleted)
  bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}



//cycle over completeTasksHolder ul list items

for(var i = 0; i < incompleteTasksHolder.children.length; i++) {

  //bind events to list items children (taskCompleted)
  bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}

4 Answers

Ferdinand Pretorius
Ferdinand Pretorius
18,705 Points

Hi Brian,

On line 74, you have checkbox surrounded by quotes. Remove the quotes.

The line should be like this

var checkbox = taskListItem.querySelector("input[type=checkbox]");

Hope this helps!

Daisho Komiyama
Daisho Komiyama
15,906 Points

At the almost bottom line, there are 2 identical lines of code as shown below

for(var i = 0; i < incompleteTasksHolder.children.length; i++) {... }

for(var i = 0; i < incompleteTasksHolder.children.length; i++) {... }

Change the second one like this

for(var i = 0; i < completedTasksHolder.children.length; i++) {...}

You're passing taskListItem as a parameter for bindTaskEvent, but never defining it within the scope of the function or in the global scope. That's why you are getting undefined. JavaScript doesn't know what to run querySelector on.

Brian Edelman
Brian Edelman
2,293 Points

Don't you normally interact with parameters inside a function like that? Whatever it is the argument will be will then be plugged into that part of the function.

Ferdinand Pretorius
Ferdinand Pretorius
18,705 Points

When using jQuery selectors, the input type does not take quotes. Good news is that you failed once and will probably remember next time :)

Good luck!

Alessandro Gilardoni
Alessandro Gilardoni
1,880 Points

I don't know why it trunkated my answer :

change this line

for(var i = 0; i incompleteTasksHolder.children.length; i++) {

to this

for(var i = 0; i completedTasksHolderTasksHolder.children.length; i++) {