1

Revised Question

How can I fix the error "Cannot read property 'addEventListener' of null" in my JavaScript code?

I have the following code for adding an event listener to a form on my website:

window.addEventListener('load', function (event) {
  const form = document.querySelector('form[data-form-id="xdf-1a43-4db-9d9a-7cgfv61282"]');
  console.log(form); // null
  form.addEventListener('submit', (event) => {});
});

However, when I run it, I get the error message "Uncaught TypeError: Cannot read property 'addEventListener' of null" in the console. It seems that the form variable is null, even though I've confirmed that the selector matches a form on the page.

How can I fix this error and add the event listener to the form successfully?

user349557
  • 83
  • 1
  • 12
  • Do you add this form element dynamically? – Konrad Jun 16 '23 at 14:55
  • I don't have control over the frontend this is an external script. Is there a way to wait until the form is present in the DOM before querySelector is ran? I'm guessing the form is added later since I can console.log it afterwards, so I know my code is right – user349557 Jun 16 '23 at 14:56
  • Your only chance here is either polling, or better, use a mutation observer on the parent element. – connexo Jun 16 '23 at 15:02
  • I voted to reopen. I'm sure that op knows why element is not found – Konrad Jun 16 '23 at 15:29
  • There is more to that question, and its answers, then "why element is not found". There are many solutions to the problem, why not add yours to the duplicate instead of adding yet another question that asks the same thing? – Heretic Monkey Jun 16 '23 at 23:04

1 Answers1

1

You can use MutationObserver to wait for items to appear in the DOM

const wrapper = document.querySelector('#wrapper')

// create observer
const observer = new MutationObserver((mutationList, observer) => {
  // for each mutation (change in the tree)
  for (const mutation of mutationList) {
    // check if the form element has been added
    const form = [...mutation.addedNodes].find(node => node.dataset.formId === 'xdf-1a43-4db-9d9a-7cgfv61282')
    if (form) {
      // attach listener here:
      console.log(form)
      form.addEventListener('submit', (event) => {});
      // remember to disconnect the observer because it's no longer needed
      observer.disconnect()
    }
  }
});

// run the observer
observer.observe(wrapper, { childList: true, subtree: true });

// simulation of form element being added by a third party:
setTimeout(() => {
  const form = document.createElement('form')
  form.dataset.formId = 'xdf-1a43-4db-9d9a-7cgfv61282'
  wrapper.appendChild(form)
}, 1000)
<div id="wrapper"></div>
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • Explanation of code, links to documentation, etc., are kind of expected on answers. Also, I expect that this question has been asked before... – Heretic Monkey Jun 16 '23 at 15:22
  • `=` assigns value to variable, `new` creates an instance of a class and `name()` calls function `name` – Konrad Jun 16 '23 at 15:26
  • Add more details to the code it self, and add a detailed explanation to the answer below. Make it a bit more organized for easy understanding. – Sebastian Gbudje Jun 16 '23 at 15:29