25

How do i make an ajax request synchronous?

I have a form which needs to be submitted. But it needs to be submitted only when the user enters the correct password.

Here is the form code:

<form name="form" action="insert.php" method="post" onSubmit="return ajaxSubmit(this);" >

And the jquery code for sending and checking password is this:

var ajaxSubmit = function(formE1) {

    var password = $.trim($('#employee_password').val());

    $.ajax({
        type: "POST",
        async: "false",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            if(arr == "Successful") {
                return true;
            } else {
                return false;
            }
        }
    });
}

However the form always submits, regardless of the value returned by the ajax request. I have checked everything else. The value of arr is coming out to be 'successful' when correct password is entered and works correctly vice versa too.

How do i make this request synchronous? as far as i can debug, the request is asynchronous so the form gets submitted before the request gets completed.

Code for checkpass.php

<?php 
require("includes/apptop.php");
require("classes/class_employee.php");
require("classes/class_employee_attendance.php");

$employee_password=$_POST['password']; 

$m=new employee();
$m->setbyid_employee(1);
$arr=$m->editdisplay_employee();

if($arr['employee_password'] == $employee_password)
{
$res="Successful";  
}
else
{
$res="Password not match";  
}

echo $res;
?>

Update: The solution has been found.

As pointed by Olaf Dietshche: The return value of ajaxSubmit is not the return value of the success: function(){...}. ajaxSubmit returns no value at all, which is equivalent to undefined, which in turn evaluates to true.

And that is the reason, why the form is always submitted and is independent of sending the request synchronous or not.

So, I set a variable to 1 inside success function upon successful. And checked its value out of success function, if it was 1 outside the success function, then I wrote return true ... else return false. And that worked.

Updated working code:

var ajaxsubmit=function(forme1) {
    var password = $.trim($('#employee_password').val());
    var test="0";

    $.ajax({
        type: "POST",
        url: "checkpass.php",
        async: false,
        data: "password="+password,
        success: function(html) {
            if(html == "Successful") {
                test="1";
            } else {
                alert("Password incorrect. Please enter correct password.");
                test="0";
            }
        }
    });

    if(test=="1") {
        return true;
    } else if(test=="0") {
        return false;
    }
}
onebree
  • 1,853
  • 1
  • 17
  • 44
Kanishk Dudeja
  • 1,201
  • 3
  • 17
  • 33

8 Answers8

42

From jQuery.ajax()

async Boolean
Default: true
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false.

So in your request, you must do async: false instead of async: "false".

Update:

The return value of ajaxSubmit is not the return value of the success: function(){...}. ajaxSubmit returns no value at all, which is equivalent to undefined, which in turn evaluates to true.

And that is the reason, why the form is always submitted and is independent of sending the request synchronous or not.

If you want to submit the form only, when the response is "Successful", you must return false from ajaxSubmit and then submit the form in the success function, as @halilb already suggested.

Something along these lines should work

function ajaxSubmit() {
    var password = $.trim($('#employee_password').val());
    $.ajax({
        type: "POST",
        url: "checkpass.php",
        data: "password="+password,
        success: function(response) {
            if(response == "Successful")
            {
                $('form').removeAttr('onsubmit'); // prevent endless loop
                $('form').submit();
            }
        }
    });

    return false;
}
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • 4
    This has been removed from recent versions of jQuery. – Reinstate Monica Cellio Dec 20 '12 at 12:06
  • 1
    @Archer From the manual: "false with **jqXHR** ($.Deferred) is deprecated". – Olaf Dietsche Dec 20 '12 at 12:10
  • On doing that, the submit button shows clicked and the page hangs. maybe the form gets submitted again and again. when i alert something inside successful if block, it gets alerted again and again. recursively. – Kanishk Dudeja Dec 21 '12 at 04:35
  • @user1865933 Ok, I missed that. When the form is submitted from the `success` function, `ajaxSubmit` is called again. Removing the `onsubmit` attribute should prevent this, however. Please try again. – Olaf Dietsche Dec 21 '12 at 08:33
  • @Olaf Dietsche: You were spot on. I set a variable to 1 inside success function upon successful. And checked its value out of success function, if it was 1 outside the success function, then i wrote 'return true', else 'return false'. And that worked. Thank you so much :) – Kanishk Dudeja Dec 21 '12 at 13:43
  • Used async: false instead of async: "false" and it worked. – Altaf Patel Mar 07 '18 at 13:59
  • $('form').submit(); didn't worked for me. Used id instead. – Michel Nov 15 '18 at 06:00
7

It's as simple as the one below, and works like a charm.

My solution perfectly answers your question: How to make JQuery-AJAX request synchronous

Set ajax to synchronous before the ajax call, and then reset it after your ajax call:

$.ajaxSetup({async: false});

$ajax({ajax call....});

$.ajaxSetup({async: true});

In your case it would look like this:

$.ajaxSetup({async: false});

$.ajax({
        type: "POST",
        async: "false",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            if(arr == "Successful") {
                return true;
            } else {
                return false;
            }
        }
    });


$.ajaxSetup({async: true});

I hope it helps :)

Fery Kaszoni
  • 3,956
  • 1
  • 18
  • 11
  • Although this is a handy way to set the default parameters for the AJAX call, it misses the actual error entirely and results in an unnecessary workaround. The `async` parameter takes a boolean, not a string. Changing it to a boolean is the solution. – Jason Aug 10 '17 at 09:24
2

Instead of adding onSubmit event, you can prevent the default action for submit button.

So, in the following html:

<form name="form" action="insert.php" method="post">
    <input type='submit' />
</form>​

first, prevent submit button action. Then make the ajax call asynchronously, and submit the form when the password is correct.

$('input[type=submit]').click(function(e) {
    e.preventDefault(); //prevent form submit when button is clicked

    var password = $.trim($('#employee_password').val());

     $.ajax({
        type: "POST",
        url: "checkpass.php",
        data: "password="+password,
        success: function(html) {
            var arr=$.parseJSON(html);
            var $form = $('form');
            if(arr == "Successful")
            {    
                $form.submit(); //submit the form if the password is correct
            }
        }
    });
});​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
halilb
  • 4,055
  • 1
  • 23
  • 31
  • @halib: the above method works. ive tried. but i dont want to resort to this way. cant we achieve this by the default onsubmit event? – Kanishk Dudeja Dec 21 '12 at 04:57
1

I added dataType as json and made the response as json:

PHP

echo json_encode(array('success'=>$res)); //send the response as json **use this instead of echo $res in your php file**

JavaScript

  var ajaxSubmit = function(formE1) {

        var password = $.trim($('#employee_password').val());    
        $.ajax({
            type: "POST",
            async: "false",
            url: "checkpass.php",
            data: "password="+password,
            dataType:'json',  //added this so the response is in json
            success: function(result) {
                var arr=result.success;
                if(arr == "Successful")
                {    return true;
                }
                else
                {    return false;
                }
            }
        });

  return false
}
halfer
  • 19,824
  • 17
  • 99
  • 186
bipen
  • 36,319
  • 9
  • 49
  • 62
  • The `async` parameter takes a boolean, not a string. The string `"false"` actually gets cast to `true` because the string is not empty. – Jason Aug 10 '17 at 09:21
1

The below is a working example. Add async:false.

const response = $.ajax({
                    type:"POST",
                    dataType:"json",
                    async:false, 
                    url:"your-url",
                    data:{"data":"data"}                        
                });                   
 console.log("response: ", response);
rudresh solanki
  • 925
  • 9
  • 4
0

try this

the solution is, work with callbacks like this

$(function() {

    var jForm = $('form[name=form]');
    var jPWField = $('#employee_password');

    function getCheckedState() {
        return jForm.data('checked_state');
    };

    function setChecked(s) {
        jForm.data('checked_state', s);
    };


    jPWField.change(function() {
        //reset checked thing
        setChecked(null);
    }).trigger('change');

    jForm.submit(function(){
        switch(getCheckedState()) {
            case 'valid':
                return true;
            case 'invalid':
                //invalid, don submit
                return false;
            default:
                //make your check
                var password = $.trim(jPWField.val());

                $.ajax({
                    type: "POST",
                    async: "false",
                    url: "checkpass.php",
                    data: {
                        "password": $.trim(jPWField.val);
                    }
                    success: function(html) {
                        var arr=$.parseJSON(html);
                        setChecked(arr == "Successful" ? 'valid': 'invalid');
                        //submit again
                        jForm.submit();
                    }
                    });
                return false;
        }

    });
 });
silly
  • 7,789
  • 2
  • 24
  • 37
0

Can you try this,

var ajaxSubmit = function(formE1) {

            var password = $.trim($('#employee_password').val());

             $.ajax({
                type: "POST",
                async: "false",
                url: "checkpass.php",
                data: "password="+password,
                success: function(html) {
                    var arr=$.parseJSON(html);
                    if(arr == "Successful")
                    { 
                         **$("form[name='form']").submit();**
                        return true;
                    }
                    else
                    {    return false;
                    }
                }
            });
              **return false;**
        }
mymotherland
  • 7,968
  • 14
  • 65
  • 122
0
var ajaxSubmit = () => {
  var password = $.trim($('#employee_password').val());
    
  ajaxsync(password, (value) => {
    if (value) {
      alert(`user Login`);
    } else {
      alert(`user not Login`);
    }
  });
}

var ajaxsync = (password, callback) => {
  $.ajax({
    type: "POST",
    url: "checkpass.php",
    data: "password="+password,
    success: function(html) {
      var arr = $.parseJSON(html);
      if (arr == "Successful") {
        callback(true);
      } else {
        callback(false);
      }
    }
  });
}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • 1
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Nov 28 '22 at 18:56