Search code examples
javascriptajaxasync-awaithttp-post

Javascript function returns from function right after await statement


I am writing client-side javascript functions to send post request to server and to get result. I am using such resources in my work:

  1. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
  2. https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  3. How do I resolve additional post request in onSubmit method in React (I do not use react, just regular javascript. Answers there mention async-await mechanism which helps you to avoid spinning callbacks).

Here is my code:

Html part - button that triggers Javascript:

<button class="btn btn-success greenbtn" id="btnFinishDay" onclick="btnFinishDay_click(event)" name="btnFinishDay" >GO</button></div>

Here is button handler:

async function btnFinishDay_click(eee) {
    var txtBarCodeValue = document.getElementById("txtBarCode").value;
    var rrr = await postAjaxWithFetch('/CheckItem', { barcodeValue: txtBarCodeValue });
    console.log(rrr);
    alert("CheckCustomer request was sent");
}

Here is how I send post request:

/*
A modern way to use POST request with form data and ajax. 
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
*/
async function postAjaxWithFetch(url, data) {
    // if data is string then use it as is. If it is Object then generate formdata string from it
    var params = typeof data == 'string' ? data : Object.keys(data).map(
        function (k) { return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }
    ).join('&');
    const request1 = new Request(url, {
        method: "POST",
        body: params,
        headers: {
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    });
    const response1 = await fetch(request1);
    console.log(response1);
    alert("hello from postAjaxWithFetch")
    return response1;
}

unfortunately right after statement with await is reached then subroutine quits. In debugger I see:

  1. btnFinishDay_click is entered
  2. await postAjaxWithFetch call is reached
  3. postAjaxWithFetch function is entered
  4. const response1 = await fetch(request1) is reached
  5. postAjaxWithFetch is stepped out, no console.log and no alert is called
  6. Network monitor does not show any /CheckItem request
  7. btnFinishDay_click finishes, no alert is shown

To sum it up - no alert calls are processed. And this feels confusing for me...

Question is: Why does async and await in regular javascript act like this disrupting normal flow?


Solution

  • It seems like the issue might be related to how the fetch API is used or possibly with the response handling. Here are a few things to check and possible fixes:

    1. Network Monitoring: If your Network Monitor doesn't show the /CheckItem request, it means the request isn't reaching the server. This could be due to:
    • An incorrect or unreachable URL.
    • The browser blocking the request due to CORS issues (Cross-Origin Resource Sharing).
    • The fetch function failing silently due to a network error or misconfigured request headers.
    1. ensure fetch is properly handling errors: Wrap the fetch call in a try-catch block to catch any errors. fetch won't throw an error on HTTP errors (like 404 or 500), but it will throw an error if the network request fails, so it's good to check for this.

    Here is a modified version of your code with error handling:

    javascript async function postAjaxWithFetch(url, data) { try { // if data is a string, use it as-is. If it is an object, generate a form-encoded string from it. const params = typeof data === 'string' ? data : Object.keys(data) .map(k => ${encodeURIComponent(k)}=${encodeURIComponent(data[k])}) .join('&');

        const request1 = new Request(url, {
            method: "POST",
            body: params,
            headers: {
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        });
    
        // Use fetch to make the request and wait for the response
        const response1 = await fetch(request1);
    
        // If fetch was successful, but the response is not ok (e.g. 404 or 500), throw an error
        if (!response1.ok) {
            throw new Error(`HTTP error! Status: ${response1.status}`);
        }
    
        // Convert response to JSON or text depending on your response format
        const data = await response1.json();  // Or response1.text() if not using JSON
        console.log(data);
        return data;
    } catch (error) {
        console.error("Error in postAjaxWithFetch:", error);
        alert("Error during POST request: " + error.message);
        return null;  // Return null or some default value in case of error
    }
    

    }

    Check the Response Type: If the server response is not JSON, and you're trying to parse it as JSON, it can cause issues. If your response is plain text, adjust your code accordingly:

    javascript const data = await response1.text(); // If your response is not JSON

    1. CORS and Server-Side Considerations:
    • CORS Issues: Ensure that your server is allowing the browser to make cross-origin requests. If the server is on a different domain than your client, you'll need to configure CORS on the server to allow the POST request.

    • Server Logs: Check your server logs to ensure it's receiving the request properly. If the server doesn't log anything, it may mean the request isn't reaching the server at all.

    Double-Check URL: Ensure that the /CheckItem endpoint is correct. It might be an issue with the relative URL or incorrect routing on the server.

    1. Debugging Tips
    • Log the request1 object before the fetch call to verify that the request is being created properly.
    • Use console.log statements throughout your async function to track its flow.

    If none of these suggestions work, please provide more details about the server and network setup so we can investigate further!