Baspa
Baspa

Reputation: 1168

Then function isn't called after returning a promise

I created a function to check if an element already exist, if not repeat the function until it does:

function waitForElementToDisplay(selector) {
    return new Promise(function (resolve, reject) {
        if (document.querySelector(selector) != null) {
            console.log('Element is displayed now');
            resolve();
        } else {
            setTimeout(function () {
                waitForElementToDisplay(selector, 500);
            }, 500);
        }
    })
}

I use this function in the beforeShowPromise function of Shepherd.js. This function let the package wait with going to the next tour step until the promise is resolved. The beforeShowPromise function looks like this:

beforeShowPromise: function () {
    return new Promise(async function (resolve) {

        const selector = '.exampleTemplates';

        await waitForElementToDisplay(selector).then(() => {
            console.log('Do something');
        }).catch(err => {
            console.log(err);
        });
    })
},

I want to wait until the waitForElementToDisplay function is resolved, so the function of Shepherd can be resolved. However, the .then nor the .catch functions are being called. Can someone explain to me why it isn't working?

Upvotes: 0

Views: 678

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 371203

You need to pass along the resolve to the recursive call:

const checkIfElementExists = (resolve, selector) => {
  if (document.querySelector(selector) !== null) {
    console.log('Element is displayed now');
    resolve();
  } else {
    setTimeout(checkIfElementExists, 500, resolve, selector);
  }
};

function waitForElementToDisplay(selector) {
  return new Promise(function(resolve) {
    checkIfElementExists(resolve, selector);
  })
}

Or, encapsulated inside waitForElementToDisplay:

function waitForElementToDisplay(selector) {
  return new Promise(function(resolve) {
    (function checkIfElementExists() {
      if (document.querySelector(selector) !== null) {
        console.log('Element is displayed now');
        resolve();
      } else {
        setTimeout(checkIfElementExists, 500);
      }
    })();
  })
}

Upvotes: 2

Quentin
Quentin

Reputation: 944530

The Promise only resolves if the element exists.

If it doesn't, you hit the else branch which calls the function recursively. This creates a new promise, but you never do anything when that resolves. The original promise is left sitting in limbo.

You can resolve the original promise with the new promise:

resolve( waitForElementToDisplay(selector) );

Upvotes: 3

Related Questions