locked
How come this Ajax return won't stop, why? RRS feed

  • Question

  • User-1651604128 posted

    Hi,

    I have a razor view, I need to add an input text field called City validation with a Save button, when Click Save button, I need to check if this City name is existed, if it is, then tell user to enter other City name, otherwise ( If this City is unique) , then process the rest codes to save the City record.

    Here is my codes:

    $(function () {
            $('#SaveCity').click(function () {
                var CITY_ID = $("#CITY_ID").val();
                 var CITY_NAME = $("#CITY_NAME").val();
                if (CITY_NAME == "") {
                    alert("You have to enter City Name");
                    document.getElementById('CITY_NAME').focus();
                    return; //Here the code is stopped here, works well            
                } else { //check duplicated cities
                     $.ajax({
                    url: '@Url.Action("CheckDuplicateCity", "City")', //here it works OK, I can find duplicate records and set result1 to a string to make result != "" to trigger the alert.
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                    success: function (result1) {
                        if (result1 != "") {
                            alert("This English Name already exists, please use another name ");
                            return;  //The problem is here, I have a duplicate record, it should stop here, but it still //execute the rest of codes and save this duplicate record.  I use the same "return" here, but it does not stop. why?// I also tried return false;              
                        }
                     }
                   });
                }
              
                $.ajax({
                    url: '@Url.Action("SaveCityData", "City")',
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME":CITY_NAME },
                    success: function (result) {                   
                        alert("Record saved successfully");
                        $('#CityIndex').html(result); 
                    }
                });
            })
        })

    My question is that why the send return won't stop, and it codes still execute to save the duplicate record?

    Tuesday, October 20, 2020 1:09 AM

Answers

  • User1686398519 posted

    Hi Peter Cong, 

    You need to change the first ajax request to be synchronous so that the execution will continue after the data is loaded.

    Here is a solution, you can refer to it.

    <script>
        $(function () {
            $('#SaveCity').click(function () {
                var CITY_ID = $("#CITY_ID").val();
                var CITY_NAME = $("#CITY_NAME").val();
                if (CITY_NAME == "") {
                    alert("You have to enter City Name");
                    document.getElementById('CITY_NAME').focus();
                    return; //Here the code is stopped here, works well
                } else { //check duplicated cities
                    var result = "";
                    $.ajax({
                    url: '@Url.Action("CheckDuplicateCity", "City")', //here it works OK, I can find duplicate records and set result1 to a string to make result != "" to trigger the alert.
                    type: 'POST',
                         data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                         async: false,
                         success: function (result1) {
                             result = result1; //When this program is executed here, it will pause and wait for the data load to complete before continuing.
                     }
                     });
                    if (result != "") {
                        alert("This English Name already exists, please use another name ");
                        return;
                    }
                }
                $.ajax({
                    url: '@Url.Action("SaveCityData", "City")',
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                    success: function (result) {
                        alert("Record saved successfully");
                        $('#CityIndex').html(result);
                    }
                });
            });
    
        });
    </script>

    Here is the result.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 20, 2020 9:04 AM

All replies

  • User1686398519 posted

    Hi Peter Cong, 

    You need to change the first ajax request to be synchronous so that the execution will continue after the data is loaded.

    Here is a solution, you can refer to it.

    <script>
        $(function () {
            $('#SaveCity').click(function () {
                var CITY_ID = $("#CITY_ID").val();
                var CITY_NAME = $("#CITY_NAME").val();
                if (CITY_NAME == "") {
                    alert("You have to enter City Name");
                    document.getElementById('CITY_NAME').focus();
                    return; //Here the code is stopped here, works well
                } else { //check duplicated cities
                    var result = "";
                    $.ajax({
                    url: '@Url.Action("CheckDuplicateCity", "City")', //here it works OK, I can find duplicate records and set result1 to a string to make result != "" to trigger the alert.
                    type: 'POST',
                         data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                         async: false,
                         success: function (result1) {
                             result = result1; //When this program is executed here, it will pause and wait for the data load to complete before continuing.
                     }
                     });
                    if (result != "") {
                        alert("This English Name already exists, please use another name ");
                        return;
                    }
                }
                $.ajax({
                    url: '@Url.Action("SaveCityData", "City")',
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                    success: function (result) {
                        alert("Record saved successfully");
                        $('#CityIndex').html(result);
                    }
                });
            });
    
        });
    </script>

    Here is the result.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 20, 2020 9:04 AM
  • User753101303 posted

    Hi,

    As pointed Ajax calls are asynchronous ie the line that follows runs immediately and it WILL later run the success callback. So another option than making the call synchronous would be to move your second Ajax call inside the first success callback.

    I suggest also later to study 'promises" and "async/await". Start maybe with https://petetasker.com/using-async-await-jquerys-ajax for the very big picture. It allows to write async code in a way that is similar to sync code compared with using nested callbacks.

    Tuesday, October 20, 2020 10:53 AM
  • User-474980206 posted

    making ajax sync, is a bad practice, and is not supported in future browsers.

    success is an async callback, so the return in it has no effect on the if statement. the second ajax call should just be in the success callback:

    $(function () {
        $('#SaveCity').click(function () {
            var CITY_ID = $("#CITY_ID").val();
            var CITY_NAME = $("#CITY_NAME").val();
            if (CITY_NAME == "") {
                alert("You have to enter City Name");
                document.getElementById('CITY_NAME').focus();
                return;          
            } else { //check duplicated cities
                $.ajax({
                    url: '@Url.Action("CheckDuplicateCity", "City")', 
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                    success: function (result1) {
                        if (result1 != "") {
                            alert("This English Name already exists, please use another name ");
                            return;               
                        }
    
                        $.ajax({
                            url: '@Url.Action("SaveCityData", "City")',
                            type: 'POST',
                            data: { "CITY_ID": CITY_ID, "CITY_NAME":CITY_NAME },
                            success: function (result) {                   
                                 alert("Record saved successfully");
                                 $('#CityIndex').html(result); 
                            }
                        });
                    };
                });
            }
        });
    });

    Tuesday, October 20, 2020 3:27 PM
  • User-1651604128 posted

    making ajax sync, is a bad practice, and is not supported in future browsers.

    success is an async callback, so the return in it has no effect on the if statement. the second ajax call should just be in the success callback:

    $(function () {
        $('#SaveCity').click(function () {
            var CITY_ID = $("#CITY_ID").val();
            var CITY_NAME = $("#CITY_NAME").val();
            if (CITY_NAME == "") {
                alert("You have to enter City Name");
                document.getElementById('CITY_NAME').focus();
                return;          
            } else { //check duplicated cities
                $.ajax({
                    url: '@Url.Action("CheckDuplicateCity", "City")', 
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME": CITY_NAME },
                    success: function (result1) {
                        if (result1 != "") {
                            alert("This English Name already exists, please use another name ");
                            return;               
                        }
    
                        $.ajax({
                            url: '@Url.Action("SaveCityData", "City")',
                            type: 'POST',
                            data: { "CITY_ID": CITY_ID, "CITY_NAME":CITY_NAME },
                            success: function (result) {                   
                                 alert("Record saved successfully");
                                 $('#CityIndex').html(result); 
                            }
                        });
                    };
                });
            }
        });
    });

    Hi bruce, thank you for your help, that is great point, 

    But I still can not use your solution, because there are more than one field have the similar validation on one razor view (Form), to save the entire form, I need all fields passed the validation. any idea for this this? 

    Thanks again

    Tuesday, October 20, 2020 3:37 PM
  • User-1651604128 posted

    Hi,

    As pointed Ajax calls are asynchronous ie the line that follows runs immediately and it WILL later run the success callback. So another option than making the call synchronous would be to move your second Ajax call inside the first success callback.

    I suggest also later to study 'promises" and "async/await". Start maybe with https://petetasker.com/using-async-await-jquerys-ajax for the very big picture. It allows to write async code in a way that is similar to sync code compared with using nested callbacks.

    Hi PatriceSc, thanks for your help, but the thing is that I have more one field have to apply the same validation rule, so in order to save, I need all fields passed the validation rule, then save it.

    Any idea? thanks

    Tuesday, October 20, 2020 3:39 PM
  • User475983607 posted

    Can you clarify your response?   As far as I can tell your original question, "How come this Ajax return won't stop, why?", has been answered.

    Now you have a new question related to validating other user inputs?   

    Tuesday, October 20, 2020 3:49 PM
  • User-1651604128 posted

    mgebhard

    Can you clarify your response?   As far as I can tell your original question, "How come this Ajax return won't stop, why?", has been answered.

    Now you have a new question related to validating other user inputs?   

    HI mgebhard, sorry for the confusing, 

    If I understood correctly for your solution, it works if my form has only one this kind of validation, but form my case, there are 2 fields which have to apply the same logic to validate.  For example, this is English Name field, I also have French Name field, so if I use your solution, each field has to use the same logic to call ajax to do the form save twice - I don't think it is a good unless I misunderstood your solution.

    I mean if I have two input text fields to apply your same validation rule, then these codes need to use for the two validation  fields, which save twice.
     $.ajax({
                    url: '@Url.Action("SaveCityData", "City")',
                    type: 'POST',
                    data: { "CITY_ID": CITY_ID, "CITY_NAME":CITY_NAME },
                    success: function (result) {                   
                        alert("Record saved successfully");
                        $('#CityIndex').html(result); 
                    }
                });

    Thanks again,

    Peter

    Tuesday, October 20, 2020 11:58 PM
  • User753101303 posted

    This is the kind of issue you have when  you want to chain multiple calls with callbacks which ends up in  having to deal with nested callbacks. I see basically two options here:
    1) take the time to study and use promises. For example https://stackoverflow.com/questions/38738614/when-all-ajax-requests-complete allows to handle multiple calls and proceed with the next steps in an easier way past understanding the feature
    2) in this particular case it seems to me it could be easier to have a single call validating the whole model (and maybe even doing the save) than to usee separate calls

    Edit: if you keep the easiest the current structure the easiest change could be to validate an array of field for uniqueness rather than a single field so that you can keep something similar but with a single call ?

    Wednesday, October 21, 2020 8:43 AM