0

Sorry if this is extremely simple, I can't get my head around it. I've seen similar questions but nothing which gets to the heart of my problem, I think. I have a simple async function:

async function isOpen() {

    var open;

    var data = $.ajax({
      //Working code here
    });

    data.done(function(dat) {
        var obj = JSON.parse(dat);
        var msg = "";

        for (var i = 0; i < obj.length; i++) {

            let closingDate = Date.parse(obj[i].close);
            let openingDate = Date.parse(obj[i].open);

            if (closingDate > Date.now() && openingDate < Date.now()) {
                open = true;
            } else {
                open = false;
            }
        }
    });

    return open;
}

I know that this code is all working - using console.log I have seen that open is always successfully assigned to true or false. So I call this async function from another async function:

async function testFunction(){

    const open1 = await isOpen();
    //More code here...

}

But open1 (in testFunction) is always undefined - even though I use await.

Any ideas what this could be?

Liam
  • 27,717
  • 28
  • 128
  • 190
Ben123
  • 335
  • 2
  • 11
  • is open also true or false if you console.log it directly before returning it? And is it still undefined if you set var open = null; at the begining? – db3000 Aug 19 '21 at 11:18
  • 2
    you `return open;` before the ajax will run – Bravo Aug 19 '21 at 11:18
  • Also, the for loop will overwrite the result of `open`, you may break the loop once your assign a value to open. – ikhvjs Aug 19 '21 at 11:19
  • 1
    Use `const dat = await data` followed by your code instead of using the `data.done()` callback. (Assuming you use jQuery 3). – 3limin4t0r Aug 19 '21 at 11:20
  • Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Liam Aug 19 '21 at 11:28

2 Answers2

3
async function isOpen() {

    var open;

    var data = await $.ajax({
      //Working code here
    });

    var obj = JSON.parse(data);
    var msg = "";

    for (var i = 0; i < obj.length; i++) {

        let closingDate = Date.parse(obj[i].close);
        let openingDate = Date.parse(obj[i].open);

        if (closingDate > Date.now() && openingDate < Date.now()) {
            open = true;
        } else {
            open = false;
        }
    }
    return open;
}

of course, the value of open will be determined by the last obj[i]

So you want

async function isOpen() {
    const data = await $.ajax({
      //Working code here
    });
    const obj = JSON.parse(data);
    let msg = "";

    for (var i = 0; i < obj.length; i++) {

        const closingDate = Date.parse(obj[i].close);
        const openingDate = Date.parse(obj[i].open);

        if (closingDate > Date.now() && openingDate < Date.now()) {
            return true;
        }
    }
    return false;
}

Or even

async function isOpen() {
    const data = await $.ajax({
      //Working code here
    });

    const obj = JSON.parse(data);
    let msg = "";
    return obj.some(({open, close}) => {
        const closingDate = Date.parse(close);
        const openingDate = Date.parse(open);
        const now = Date.now();
        return closingDate > now && openingDate < now();
    });
}
Bravo
  • 6,022
  • 1
  • 10
  • 15
2

This is happening because you are using a callback for ajax request and not waiting for ajax request to complete, which is going to set open in isOpen. You can return a Promise to resolve this,

function isOpen() {
  return new Promise((resolve, reject) => {
    var open;

    var data = $.ajax({
      //Working code here
    });

    data.done(function(dat) {
        var obj = JSON.parse(dat);
        var msg = "";

        for (var i = 0; i < obj.length; i++) {

            let closingDate = Date.parse(obj[i].close);
            let openingDate = Date.parse(obj[i].open);

            if (closingDate > Date.now() && openingDate < Date.now()) {
                open = true;
            } else {
                open = false;
            }
        }
       resolve(open);
    });

  }
}

Note: For the above code, you need to handle the logic for errors in the callback, using reject otherwise it will hang forever.

Utkarsh Dixit
  • 4,267
  • 3
  • 15
  • 38