1

I know there are stacks of ways this could be possible. And I also understand settimeout is async and "true" can't easily be returned, without promises.

But I'm struggling to return true from this function, with promises.

What is the best way I can return true, from this snippet of code? (I want to return true, IF an element exists).

I need to be able to specificially return true.

Or is there another way I can achieve this. Waiting for a DOM element to exist on a page and return true when it does?

function waitForElement(className, callBack){
    return new Promise(function(resolve) {
        window.setTimeout(function(resolve){
            var element = document.querySelector(className);
            if(element) {
                callBack(className, element);
                console.log("Element exists")
            } else {
                waitForElement(className, callBack);
                console.log("Wait...")
            }
        },1000)
    });
};

waitForElement(".helping-hand-sliding-data h2",function(){
    return true;
});
Reena Verma
  • 1,617
  • 2
  • 20
  • 47

1 Answers1

2

It's better not to mix promises and callbacks. Just invoke resolve(element) once it's ready and await the whole thing:

function waitForElement(className) {
    return new Promise(function (resolve) {
        function wait() {
            let element = document.querySelector(className);
            if (element) {
                resolve(element)
            } else {
                window.setTimeout(wait, 500)
                console.log("Wait...")
            }
        }
        wait()
    });
}

setTimeout(function() {
    let fake = document.createElement('div')
    fake.className = 'helping-hand-sliding-data'
    document.body.appendChild(fake)
}, 2000)


async function main() {
    let element = await waitForElement(".helping-hand-sliding-data");
    console.log('FOUND!', element)
}

main()
georg
  • 211,518
  • 52
  • 313
  • 390
  • Thank you @georg! I don't think this returns "true" though. I can see a promise is returned: Promise {: undefined} __proto__: Promise [[PromiseState]]: "fulfilled" [[PromiseResult]]: undefined – Reena Verma Jun 23 '21 at 11:02
  • @ReenaVerma The `waitForElement()` promise fulfills with the element. The `main()` promise fulfills with `undefined`. At no point you need the value `true`. – Bergi Jun 23 '21 at 11:03
  • You cannot return anything from an async function, see https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call/14220323#14220323 – georg Jun 23 '21 at 11:04
  • ok thank you. The application I'm using is specifically looking for a "return true/or something" rather than a promise. I wondered if there was another way I could achieve this? – Reena Verma Jun 23 '21 at 11:09
  • If you have a strictly synchronous flow, there's no way you can integrate an async action into it. Javascript can't just stop running and wait for something. – georg Jun 23 '21 at 11:13