Event handlers on dynamically generated DOM element : does not work until page refresh

I have a dynamically generated list with delete buttons on each of the list items. The delete button has an event handler to listen for click event. If I create a list item and click on the newly generate items Delete button, nothing happens. The other delete event handlers work fine. On page refresh, the latest delete button also works.

let buttonsList = document.querySelectorAll('.delete')
for (let i = 0; i < buttonsList.length; i++) {
  buttonsList[i].addEventListener('click', (e) => {
    const buttonId = e.target.dataset['id']
    console.log('Event >>> ', e)
    fetch('/todos/' + buttonId + '/delete', {
        method: 'DELETE',
      })
      .then(() => {
        document.getElementById('errorText').className = 'hidden'
        console.log('Got response from server')
        const itemToDelete = e.target.parentElement
        itemToDelete.remove()
      })
      .catch((err) => {
        console.log("Error >>> ", err)
        document.getElementById('errorText').className = ''
      })
  })
}

It would be helpful to see more of your code and how this code is structured with respect to the other code. Do you have a codepen link you could share the full code?

It is a little hard to help without seeing more of the code, but I’m assuming your event listener setup code only runs one time. That doesn’t really work for dynamically created elements. When you add elements dynamically to the DOM you would have to add the event listener again to the new elements.

Use some ancestor element (even the document if needed) that is not added or remove dynamically and add the event listener to it. Then do event delegation (google event delegation).

1 Like

@RandellDawson I am sharing the repl link
@lasjorg That sounds exactly what is happening. The event listener is not implemented on the newly created items but does work on previous elements. Do you mean to say I should have another event listener on a super element(for the lack of a better term) so that it runs whenever a new element is created?

You should remove the existing event listeners on the buttons and checkboxes and instead create a single click event listener and single change event listener for the ul element. Then, you write logic to validate which event occurred and what element it occurred on. You can tell which element was affected by checking the class name.

There is a good example of doing what I explain above in the Medium article @lasjorg referenced above. Give it a try. If you get stuck, post a link to your new code.

Note: Please do not change the category from “Programming Help”. Thank you

1 Like

Thanks a lot @lasjorg and @RandellDawson for guiding me in the right direction. Event delegation is the way forward for handling events on dynamic elements. :slight_smile:
Also, I am sorry for changing the category, I was under the impression I had chosen the wrong one to begin with.

No, you were seeking help with code. The Web Development category is for discussing more broad topics about Web Development vs how to do something very specific with code.

1 Like