skip to Main Content

I have this function to delete items once a popup returns true:

function deleteItems(selectedItems){
    if (selectedItems.length > 0) {
        $("#confirm-popup-modal").modal("show");
        $("#confirm-popup-modal").one('hidden.bs.modal', function (event) {
            if ($("#confirm-modal").val() == "true") {
                var form_data = selectedItems;
                $.ajax({
                    url: "@Url.Action("Delete", @ViewContext.RouteData.Values["controller"].ToString())",
                    method: "POST",
                    data: JSON.stringify(form_data),
                    contentType: "application/json",
                    success: function (result) {
                        if (result.Result == true) {
                            var deleteId = result.Output;
                            await CompletedJobsAccess(deleteId);
                            table.draw();
                        }
                    },
                    error: function (error) {
                        console.log(error);
                    }
                });
            }
        });
    }
}

Inside the Ajax success is another function called CompletedJobsAccess that will keep looping every 3 seconds to check if a job deletion has been completed:

function CompletedJobsAccess(DeleteId){
    return new Promise((resolve,reject)=>{
        var loopInterval = setInterval(function() { 
            $.ajax({
                url: "@Url.Action("Verify", "CompletedJobsAccess", new {area="Base" })",
                method: "POST",
                data: JSON.stringify(DeleteId),
                contentType: "application/json",
                success: function(verifyResult) {
                    if (verifyResult.IS_COMPLETED == true && verifyResult.IS_PROCESSING == false) {
                        if (verifyResult.IS_SUCCESSFUL == true) {
                            console.log(verifyResult.OUTPUT);
                            $.each($.parseJSON(verifyResult.OUTPUT), function(index, value) {
                                if (value.Result == true) {
                                    toastr.success(value.Message);
                                }else{
                                    toastr.error(value.Message);
                                }
                            });
                            clearInterval(loopInterval);
                        } else {
                            toastr.error(verifyResult.ERROR_MESSAGE);
                        }
                    }
                },
                error: function(innerError) {
                    console.log(innerError);
                }
            });
        }, 3000);
    });
}

However, when I load the page, and call deleteItems(selected);, this is the error I get:

Uncaught SyntaxError: await is only valid in async functions and the
top level bodies of modules

I tried searching around but I can’t find if it can work within an ajax success function.

EDIT:

Added async to the ajax success function but the table draw function doesn’t run.

function deleteItems(selectedItems){
    if (selectedItems.length > 0) {
        $("#confirm-popup-modal").modal("show");
        $("#confirm-popup-modal").one('hidden.bs.modal', function (event) {
            if ($("#confirm-modal").val() == "true") {
                var form_data = selectedItems;
                $.ajax({
                    url: "@Url.Action("Delete", @ViewContext.RouteData.Values["controller"].ToString())",
                    method: "POST",
                    data: JSON.stringify(form_data),
                    contentType: "application/json",
                    success: async function (result) {
                        if (result.Result == true) {
                            var deleteId = result.Output;
                            console.log("table before");
                            await CompletedJobsAccess(deleteId);
                            console.log("table draw");
                            table.draw();
                        }
                        table.draw();
                    },
                    error: function (error) {
                        console.log(error);
                    }
                });
            }
        });
    }
}

EDIT 2: Updated CompletedJobsAccess to resolve promises:

function CompletedJobsAccess(DeleteId){
    return new Promise((resolve,reject)=>{
        var loopInterval = setInterval(function() { 
            $.ajax({
                url: "@Url.Action("Verify", "CompletedJobsAccess", new {area="Base" })",
                method: "POST",
                data: JSON.stringify(DeleteId),
                contentType: "application/json",
                success: function(verifyResult) {
                    if (verifyResult.IS_COMPLETED == true && verifyResult.IS_PROCESSING == false) {
                        if (verifyResult.IS_SUCCESSFUL == true) {
                            console.log(verifyResult.OUTPUT);
                            $.each($.parseJSON(verifyResult.OUTPUT), function(index, value) {
                                if (value.Result == true) {
                                    toastr.success(value.Message);
                                }else{
                                    toastr.error(value.Message);
                                }
                            });
                            clearInterval(loopInterval);
                            return Promise.resolve();
                        } else {
                            toastr.error(verifyResult.ERROR_MESSAGE);
                            return Promise.resolve();
                        }
                    }
                },
                error: function(innerError) {
                    console.log(innerError);
                }
            });
        }, 3000);
    });
}

4

Answers


  1. Try Adding async before all the function keyword like async function deleteItems(selectedItems){ and also $("#confirm-popup-modal").one('hidden.bs.modal', async function (event) { and it should do the job.

    Login or Signup to reply.
  2. Just make the success function async

    $.ajax({
      url: "https://jsonplaceholder.typicode.com/users/3",
      method: "GET",
      success: async function(data) {
        console.log("first - now wait a second ...");
        await new Promise((res) => setTimeout(res, 1000));
        console.log("second, data:",data);
      },
      error: function(innerError) {
        console.log(innerError);
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    Working JSFiddle (can’t work on this site because of CORS)

    Login or Signup to reply.
  3. You’re using await in functions that don’t use the async keyword. await isn’t available in regular functions. To solve this, you can change all the functions using await to async function to make it into an asynchronous function.

    And if you don’t want want to go through every function to make it asynchronous, you can just put the entire code inside an asynchronous IIFE

    Login or Signup to reply.
  4. In CompletedJobsAccess(DeleteId) you return a promise. But the way you set it up it will never execute the resolve function. So your await will wait forever …

    You could place the line

    resolve();
    

    right after

    clearInterval(loopInterval);
    

    in your CompletedJobsAccess function to make it work.

    Do not return yet another Promise.resolve() like you did in your edited code.

    A resolve function for a promise is never returned but executed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search