32

I have a VERY simple jQuery Ajax call (below). The Ajax call executes and I can see in the Firebug Net panel that the server returned 200 OK and returned a string "OK" as it should. However, the done and fail functions do not fire! Very frustrating!

(The "before" and "after" alerts DO fire. )

For simplicity (and as a debugging technique) I have stripped this down to it's most bare skeleton but still the handlers won't fire. What am I not seeing here?

postUrl= "/mod/users/check_email/";
dataToPost= { email: "test@not.me" };

alert("before");
$.ajax
({
    type: "POST", 
    url: postUrl,
    data: dataToPost,
    done: function() 
    {
        alert("Success.");
    },
    fail: function() 
    {
        alert("Sorry. Server unavailable. ");
    },
});  // end Ajax call 

alert("after");
misterrobinson
  • 391
  • 2
  • 4
  • 6

5 Answers5

57

You need to chain the done() and fail() functions, they are not part of the options object used in $.ajax :

$.ajax({
    type: "POST", 
    url : postUrl,
    data: dataToPost
}).done(function()  {
    alert("Success.");
}).fail(function()  {
    alert("Sorry. Server unavailable. ");
}); 

Also, as ajax is asynchronous, don't be suprised if the "after" alert comes before the "success" alert.

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Thanks very much!! That worked like a champ. I was switching from old success and error examples to done and fail. – misterrobinson May 24 '13 at 22:04
  • @misterrobinson - Yes, it can be a litte confusing, but the new methods aren't part of the object, as they are much more universal an can be used on any deferred/promise, like what the $.ajax function returns. – adeneo May 24 '13 at 22:20
  • 1
    There is also the always **.always(function() {//code here})** which you can use to stop items like progress spinner. It is a replacement for **complete**. For the actual start of the spinner, you need to go back inside the Ajax-setup and add **beforeSend: function() {//code here: start spinner}**. – Ajowi Feb 26 '21 at 14:15
15

success and error callbacks can be used in that way. For done and fail, you need to do :

$.ajax({
    type: "POST", 
    url: postUrl,
    data: dataToPost,
}).done(function() {
    alert("Success.");
}).fail(function() {
    alert("Sorry. Server unavailable. ");
});

Or :

$.ajax({
    type: "POST", 
    url: postUrl,
    data: dataToPost,
    success: function() {
            //code here
    }
});
Mustafa Genç
  • 2,569
  • 19
  • 34
14

Also you need to set dataType: 'json'. I ran into this problem when I set it to 'string' and it doesn't fire the done method.

vqdave
  • 2,361
  • 1
  • 18
  • 36
WtFudgE
  • 5,080
  • 7
  • 47
  • 59
  • 1
    When doing this, please ensure that the returned value is a well formatted JSON string, otherwise the done() function will never call (which is what I was scratching my head over!). – Smithee Oct 20 '22 at 09:40
12

I have the same setup like this:

$.ajax({
    type: "POST", 
    url : postUrl,
    data: dataToPost
}).done(function()  {
    alert("Success.");
})

and ran into the same problem: the done function wouldn't fire off. Though I've managed to make it work many times before with the same set up, it took me a while to figure out what happened. After tweaking around, I found that it also depends on the type of data returned by the Ajax call. Originally, I configured the ajax call to return some HTML. The done function didn't work. After I changed it back to json (with jsonify in Flask,) it works again.

Toàn Nguyễn
  • 371
  • 3
  • 6
2

async Set to false if the request should be sent synchronously. Defaults to true. Note that if you set this option to false, your request will block execution of other code until the response is received.

dataType The type of data you expect back from the server. By default, jQuery will look at the MIME type of the response if no dataType is specified.

Remove dataType: 'json' if existed.

Add async:false if not existed.

Execute like this:

var username=$("#username").val();
var password=$("#password").val();
$.ajax({
    url: "addperson.php",
    type: "POST", 
    async: false,
    data: {
        username: username,
        password: password
    }
})
.done (function(data, textStatus, jqXHR) { 
   var obj = JSON.parse(data);
   //Handle the response data here
    alert(obj.success); 
})
.fail (function(jqXHR, textStatus, errorThrown) { 
    alert("Error"); 
})
.always (function(jqXHROrData, textStatus, jqXHROrErrorThrown) { 
    alert("complete"); 
});

The addperson.php echo in JSON format like this:

$username1 = isset($_POST["username"]) ? $_POST["username"] : '';
    
$password1 = isset($_POST["password"]) ? $_POST["password"] : '';

$servername = "xxxxx";
$username = "xxxxx";
$password = "xxxxx";
$dbname = "xxxxx";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}

$sql = "INSERT INTO user (username, password)
VALUES ('$username1', '$password1' )";

    ;  
    
    
   

if ($conn->query($sql) === TRUE) {
    
   echo json_encode(array('success' => 1));
} else{
    
    
  echo json_encode(array('success' => 0));
}





$conn->close();