1

I'm relatively new to Javascript and haven't been able to figure out a way to make my code wait for some result before it executes the next steps. I did some research on callbacks, but I can't seem to make it work with my code.

I am using the Flask framework to develop a webpage. The following code calls one of the endpoints to get a JSON response (name is the parameter I'm sending to the endpoint and data is the JSON response I get back):

$.getJSON('/if_name_exists', {
    name: "sample_name",
}, function(data) {
    if (data.check == "True") {
        alert("Name already exists! Please enter another name.");
        return false;
    }
});

The problem is that Javascript doesn't wait for this response and executes the next steps in my program. This is what I've tried-

$.getJSON('/if_name_exists', {
    name: "sample_name",
}, function(data) {
    if (data.check == "True") {
        alert("Name already exists! Please enter another name.");
        return false;
    }
});

(async () => { await wait(2000); console.warn('done') })();

But my code still doesn't wait for the response and executes the next steps. How do I solve this issue?

kev
  • 2,741
  • 5
  • 22
  • 48

1 Answers1

1

Short Answer

With a promise, or a callback.

It looks like you're trying to make an async function, which awaits the response / error from your ajax request.

See below for a working example, 2 functions are defined, one is the function that makes the request 'makeRequest', this returns a Promise, which resolves when your network request succeeds or fails.

The second function is the function that calls the function that makes the request, here you'll see i've placed a try/catch example.

This looks to be what you're after.

const makeRequest = async () => {
    return new Promise((resolve, reject) => {

        $.getJSON('/if_name_exists', {
            name: "sample_name",
        }, function(data) {
            if (data.check == "True") {
                alert("Name already exists! Please enter another name.");
                return resolve(false);
            }

            return resolve(true);
        }, reject);

    })
};

const runRequest = async () => {
    try {

        const result = await makeRequest();

        // This will not log until your request has succeeded.
        console.log(`Result = ${result}`);
    } catch (e) {
        console.log("Error making request", e);
    }
}



// Run the request
runRequest();

Sounds like you ought to look up Promises, callbacks, and asynchronous control flow in general, be worth the read!

You could write runRequest without async/await, just using the Promise API. E.g.

const runRequest = () => {

    makeRequest()
        .then((result) => {
            console.log(`Result = ${result}`);
        })
        .catch((error) => {
            console.log("Error making request", e);
        });
}

Or finally, you could write it using callbacks.

const makeRequest = (success, error) => {
    $.getJSON(
        "/if_name_exists",
        {
            name: "sample_name"
        },
        success,
        error
    );
};

const runRequest = () => {
    makeRequest(
        data => {
            if (data.check == "True") {
                alert("Name already exists! Please enter another name.");
                return resolve(false);
            }
        },
        error => {
            console.log("Error making request", e);
        }
    );
};

// Run the request
runRequest();

Note: If $.getJSON returns a promise, then you can omit the Promise constructor call, unsure if it did or not, i.e. just supports callbacks, so I have explicitly returned a promise in makeRequest.

Lee Brindley
  • 6,242
  • 5
  • 41
  • 62
  • Hi, thanks for answering. I tried your first solution but it doesn't seem to work. For example, this `$.getJSON` code snippet is inside another function which should ideally be exited depending on the response. However, the next lines still get executed - for example, there is an `alert("message")` after this that still gets displayed. – kev May 17 '19 at 20:55
  • Sounds like you want the resolve(false) to be reject(false). That would trigger the catch if, in your example data.check === "True" – Lee Brindley May 17 '19 at 20:58
  • Tried that too, not working :/ – kev May 17 '19 at 21:06
  • Then I suspect something else is wrong in your code. The snippets in my answer are all very basic examples of Promises with async/await and without, and with simple callbacks – Lee Brindley May 18 '19 at 12:26