0

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 4

1

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)

Sign up to request clarification or add additional context in comments.

4 Comments

I put async in the success function but it doesn't run the console log after. I updated the question with an Edit.
@JianYA you never resolve your promise inside CompletedJobsAccess
If you pick an existing (CORS enabled) site then AJAX will work from SO too. I just edited this answer accordingly.
How do I return a promise inside my function properly? I updated my question with another edit showing what I did.
1

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.

1 Comment

How do I return a promise inside my function properly? I updated my question with another edit showing what I did.
0

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.

Comments

0

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

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.