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 JavaScript and the DOM (Retiring) Traversing the DOM Getting the First and Last Child

Joseph Michelini
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Joseph Michelini
Python Development Techdegree Graduate 18,692 Points

Why is my function not firing when there is a click?

I've written a function that will remove the first and last child of listUl, which selects the unordered list holding my list items. I've placed the function at the end of the click event handler for the remove button, but it does nothing.

function firstLastHide() {
  let first = listUl.firstElementChild;
  let last = listUl.lastElementChild;
  let up = first.querySelector('.up');
  let down = last.querySelector('.down');
  first.removeChild(up);
  last.removeChild(down);
  }

listUl.addEventListener('click', (event) => {
  if (event.target.tagName == 'BUTTON') {
    if (event.target.className == 'remove') {
    let li = event.target.parentNode;
    let prevLi = li.previousElementSibling;
    let nextLi = li.nextElementSibling;
    let ul = li.parentNode;
    ul.removeChild(li);
    firstLastHide();
  }
}

I've even modified it so it takes ul as an argument, and still it does nothing. If anyone is able to help I'd be so grateful! Losing sleep!

function firstLastHide(currentList) {
  let first = currentList.firstElementChild;
  let last = currentList.lastElementChild;
  let up = first.querySelector('.up');
  let down = last.querySelector('.down');
  first.removeChild(up);
  last.removeChild(down);
  }

listUl.addEventListener('click', (event) => {
  if (event.target.tagName == 'BUTTON') {
    if (event.target.className == 'remove') {
    let li = event.target.parentNode;
    let prevLi = li.previousElementSibling;
    let nextLi = li.nextElementSibling;
    let ul = li.parentNode;
    ul.removeChild(li);
    firstLastHide(ul);
  }
}

The only other thing I can think of is to write a bunch of conditional statements for each button inside the click event handler to determine its position and what buttons the <li> around it should have after the click, but that seems like a lot of code...which always leads me to believing I might be doing something wrong.

I found this code from someone else's solution that works, but besides it hiding the up and down button instead of removing them, I can't understand what the functional difference is between this and what I'm trying.

function checkButtons () {
  let firstListItemUpButton = listUl.firstElementChild.querySelector('button.up');
  firstListItemUpButton.style.visibility = 'hidden';
  let lastListItemUpButton = listUl.lastElementChild.querySelector('button.down');
  lastListItemUpButton.style.visibility = 'hidden';
};

Thank you!

1 Answer

Steven Parker
Steven Parker
231,268 Points

The "addEventListener" function has unbalanced parentheses and braces.
It needs an additional "});" at the end.

Joseph Michelini
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Joseph Michelini
Python Development Techdegree Graduate 18,692 Points

Hey Steven, I actually didn't include all of the code here but "addEventListener" is balanced and closed correctly in my workspace. Thank you, appreciate you.

Steven Parker
Steven Parker
231,268 Points

After making that change to the original code, it worked as expected; removing both buttons along with the line clicked.

Problems can be caused by parts of the code you may not expect. Perhaps you could make a snapshot of your workspace and post the link to it here, to allow accurate replication of the issue.

Joseph Michelini
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Joseph Michelini
Python Development Techdegree Graduate 18,692 Points

Hey Steven, following your advice I've created a snapshot here: https://w.trhou.se/dz318lrp5p

Notice when you load the preview, if you click the "remove" button on the last list item, the new last list item, which I assume would be determined by the function firstLastHide(), still has the buttons it started with, the function doesn't hide the down button again.

This function seems to work at the top of the program though! When you preview it, you'll notice no down button on the last list item and no up button on the first list item, since the function firstLastHide() is called before the click event. Why doesn't this function determine the first and last list items again and hide the up and down buttons when it is called at the bottom of the click event?

I should mention console it also throwing an error when I click "remove" on the last list item, but I'm having trouble understanding it.

Thank you for your time! I realize this is a small thing but it's driving me nuts, and I worry I may be misunderstanding some sort of fundamental structure about my code.

Thank you.

Steven Parker
Steven Parker
231,268 Points

After the function has run, there is no longer any "up" button on the first item. So when running it a 2nd time, the step intended to remove the "up" button fails and ends the function before the "down" button can be removed.

You can easily test if the buttons exist before attempting to remove them:

  if (up) first.removeChild(up);
  if (down) last.removeChild(down);