querySelectorAll is not returning updated nodelist inside a recursive function

61 views Asked by At

I am trying to grab an element in the DOM that is created in the future. To simplify, When the user uploads an image by clicking on an upload button, a div is created in the DOM, which has a class name of ".popup".

To check if the modal with class name ".popup" is created I am using a recursive function. And it works fine when I use the querySelector method.

The problem is, the user can upload multiple files, which will create multiple divs in the DOM with the same class name. When I use the querySelectorAll method to grab all the divs it always returns the first div, and does not grab the other ones. Looks like the let modals = document.querySelectorAll(".popup") does not update inside the recursive function.

Any suggestions, what am I missing here?

Thanks in advance.

const attachRemoveBgEvent = () => {
  const input = document.getElementsByTagName("input");
  for (var i = 0; i < input.length; i++) {
      //Add Listner
      input[i].addEventListener("input", checkCropper);
  }
};

async function checkCropper(e) {
  async function checkModalIsCreated() {
    return new Promise((resolve) => {
      function checkModal() {
        let modals = document.querySelectorAll(".popup");
        if (modals.length > 0 ) {
          createRemoveButton(modals);
          resolve();
        } else {
          setTimeout(checkModal, 1000);
        }
      }
      checkModal();
    });
  }

  await checkModalIsCreated();

}

const createRemoveButton = (modals) => {
console.log(modals);
}

I am expecting to get all the divs with the class name ".popup" if there is multiple of them get created in future. But I only get the first one, even if I am using querySelectorAll() method which should return a nodelist with all the divs that has that class name.

I also tried using getElementsByClassName() which returns a live HTMLcollection. But in the console, I do see the HTMLcollection contains all the items, but when I console.log the length, it's always one.

1

There are 1 answers

0
Al Amin Khan On

I have solved the issue, I just had to keep track of the popup I already found, and check if the length of the nodelist is larger.

// total number of popup found
let popupFound = 0;

const attachRemoveBgEvent = () => {
  const input = document.getElementsByTagName("input");
  for (var i = 0; i < input.length; i++) {
      //Add Listner
      input[i].addEventListener("input", checkCropper);
  }
};

async function checkCropper(e) {
  async function checkModalIsCreated() {
    return new Promise((resolve) => {
      function checkModal() {
        let modals = document.querySelectorAll(".popup");
        if (modals.length > popupFound ) {
          popupFound = popupFound + 1;
          createRemoveButton(modals);
          resolve();
        } else {
          setTimeout(checkModal, 1000);
        }
      }
      checkModal();
    });
  }

  await checkModalIsCreated();

}

const createRemoveButton = (modals) => {
console.log(modals);
}