1

I went through many posts about this, but didnt find any solution working for me - cleaned up code:

  $('#form-new').submit(function(e){
    e.preventDefault();

    $curForm = $(this);
    $textbox = $( '.new-box' ,this);

    window.tmp_input_ok = false;

    var wasError = false;
    if( $.trim($textbox.val()) == "" ){  
      wasError = true; 
    }    

    if( wasError ){
      //possible message
    } else{

      var jqxhr = $.post(
        $(this).attr('action'),
        $(this).serialize(),
        function(data, textStatus, jqXHR){

          if( data=="200" ){
            console.log('post OK'); //this shows in console!
            window.tmp_input_ok = true;  
          } else{
            console.log('not OK');       
          } 

        }
      ).fail(function() {
        console.log('POST fail)');
      });    

    }

    //however, window.tmp_input_ok is false here so the textbox does not empty:
    if(window.tmp_input_ok == true) $textbox.val(''); 
      else console.log('input not ok :('); //and this is outputted to console

  }); 

Originaly, there was just a var tmp_input_ok = false initialization and then working with the tmp_input_ok variable, but it wasnt working so I tried global window... does not work either... I am starting to be desperate.

Incognito
  • 20,537
  • 15
  • 80
  • 120
jave.web
  • 13,880
  • 12
  • 91
  • 125
  • 6
    The `$.post()` call is asynchronous. The function returns immediately, but the callback you pass in is not invoked until the HTTP response is received. – Pointy Dec 11 '13 at 16:18

2 Answers2

2

Your if statement is executed before the call is finished.

$.post is an async call and the rest of the code continues while the post is processing

You are already using .fail(), you can add .always() if you want to execute your if statement always on completion or add it to your .success() if you only want to check it when the call succeeds, similar to this:

if (wasError) {
    //possible message
} else {
    var jqxhr = $.post($(this).attr('action'), $(this).serialize(), function (data, textStatus, jqXHR) {
        if (data == "200") {
            console.log('post OK'); //this shows in console!
            window.tmp_input_ok = true;
        } else {
            console.log('not OK');
        }

        // either add it here if you only want to process it on success
        if (window.tmp_input_ok == true) $textbox.val('');
        else console.log('input not ok :(');
    }).fail(function () {
        console.log('POST fail)');
    }).always(function(){ // or add it here if you always wan to execute on completion regardless of fail or success
        if (window.tmp_input_ok == true) $textbox.val('');
        else console.log('input not ok :(');
    });
}
Nope
  • 22,147
  • 7
  • 47
  • 72
  • 1
    Just for better readability and consistency I'd put the success handler code into the `.done()` function, like as with `.fail()` and `.always()`. – Simon Dec 11 '13 at 16:30
  • ah Ive forgot about the async processing .... that is the problem, let me checked that out... – jave.web Dec 11 '13 at 16:31
  • It is working ! :) (you've just save my life :P ) , BTW - always() - is it always executed AFTER success and fail are processed? – jave.web Dec 11 '13 at 16:38
  • @jave.web: I'm not quite sure if `always` is execute after or at the same time then `done`/`fail`. I suppose you could add all of them with console output and check but I don't know if I would write code to rely on the order explicitly. – Nope Dec 11 '13 at 16:44
  • Ok so I will stay at my current solution that calls an external action in each state :) Thanks again! – jave.web Dec 11 '13 at 16:46
  • 1
    @jave.web: I just had another look at the [**Ajax Events Documentation**](http://api.jquery.com/Ajax_Events/) and under the Events section is says: `This is the full list of Ajax events , and in the order in which they are triggered.` it then lists all the events and it lists them as `success`, `fail`, `complete` but again, I'm not quite certain how reliable that will be if you write code depending on that order. – Nope Dec 11 '13 at 16:48
1

The reason your XHR request has an onSuccess callback is because the call is asynchronous.

Take for instance this simple bit of code:

$.get(
    '/foo',
    function(){
        alert("data received");
    }
)

alert ("End of script reached");

The success callback is set up to something that will be called when the request is successfully received, rather than when that line of code is read by the browser.

Often you'll see the "End of script reached" alert before the "data received" alert simply because a full XHR request will take over 100 milliseconds, while reading those few lines will take a fraction of that.

Code that depends on having a response for a state must be called by the callback. There's far too many ways to do this for me to go into detail.

Incognito
  • 20,537
  • 15
  • 80
  • 120