1

Through ajax call i am updating something and returning false and true. but the problem is that before i get result value from update function the if condition that is present after update function is executed and thus it give an error undefined result and errMsg variable. If I write this code again then it works. how i can stop running if condition until my update function returns some value?

var result = update(field_name, field_value);

if (result == false) {
  alert(errMsg);
} else {
  alert(errMsg);
}

update function

function update(field_name, field_value) {
  if (field_value) {
    $.post("/restapi/vc/users/id/${user.id}/profiles/name/" + field_name + "/set?value=" + field_value, function(data, status) {
      var xmlDoc = data;
      var x = xmlDoc.getElementsByTagName("response")[0];
      var txt = x.getAttribute("status");
      if (txt == 'error') {
        var msg = xmlDoc.getElementsByTagName("message")[0];
        var errMsg = msg.childNodes[0];
        window.errMsg = errMsg.nodeValue;
        return false;
      } else {
        return true;
      }
    });
  }
}
Tamir Vered
  • 10,187
  • 5
  • 45
  • 57
Tariq Husain
  • 559
  • 5
  • 23

4 Answers4

0

because update function returns a void/null. and null is == to false.

var result = update(field_name,field_value);
//update method is called and returns null 
if(result == false){  //null == false is true
    alert(errMsg);  //this line will execute
}else{
    alert(errMsg);
}

this is happening because of async nature of JavaScript. window.errMsg is being set after it is alerted. ajasx post in update method is a ajax request and its sucess method is called async.

better way withtout using Deffered would be to use callback.

var update = function update(field_name, field_value, callback) {
    if (field_value) {
        $.post(
            "/restapi/vc/users/id/${user.id}/profiles/name/" + field_name + "/set?value=" + field_value,
            function(data, status) {
                var xmlDoc = data;
                var x = xmlDoc.getElementsByTagName("response")[0];
                var txt = x.getAttribute("status");
                if (txt == 'error') {
                    var msg = xmlDoc.getElementsByTagName("message")[0];
                    var errMsg = msg.childNodes[0];

                    //its not good practice to add 
                    //transactional messages to window/global scope
                    //window.errMsg = errMsg.nodeValue;  

                    //return false;   
                    //instead of return call the callback
                    callback(errMsg.nodeValue);
                } else {
                    //return true;
                    //likewise in case of success
                    callback();
                }
            }
        );
    }
};

//and call update method like this -
update(field_name, field_value, function(errMsg){
    if (errMsg) {
        alert(errMsg);  //alert the error message
    } else {
        alert('success');
    }
});
Mohit
  • 2,239
  • 19
  • 30
0

There are two way to call update function after the ajax call

1) Call update function in response of the ajax call

2) Call Ajax as synchronous by setting async:false in ajax call

Link for more information synchronous on ajax call will be here How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

Community
  • 1
  • 1
Mitul
  • 3,431
  • 2
  • 22
  • 35
0

The problem here is that your if condition is executing before the ajax request is done. Ajax works asynchronously, meaning it executes in a background process and the main javascript execution doesn't wait for it to finalize to progress.

errMsg will never get the value from within the ajax callback since it will execute most probably before the ajax is done

You can simply alert the message from within the post callback function :

function update(field_name, field_value){
                 if(field_value){
                   $.post("/restapi/vc/users/id/${user.id}/profiles/name/"+field_name+"/set?value="+field_value, function(data, status){
                      var xmlDoc = data;
                      var x = xmlDoc.getElementsByTagName("response")[0];
                      var txt = x.getAttribute("status");
                       if(txt == 'error'){
                        var msg = xmlDoc.getElementsByTagName("message")[0];
                        var errMsg = msg.childNodes[0];
                        alert(errMsg); // alert the message here
                        } else{
                          return true;
                        }

                    });
                   }
               }
KAD
  • 10,972
  • 4
  • 31
  • 73
  • thanks for the explanation but errMsg have global scope window.errMsg make it work globally but still it wont work for the first time. – Tariq Husain Oct 12 '15 at 05:39
  • I have missed the `window.errMsg` setting, but still it won't get set at the global scope because of AJAX, it will still be undefined. Why can't you use it directly within the callback? – KAD Oct 12 '15 at 05:46
  • because im not only alerting this msg i have some other queries too. i alert it just to check if im getting the result or not so i can perform further queries , – Tariq Husain Oct 12 '15 at 05:51
  • well wrap your code in a function and pass the message to it `processAfterAjax(errMsg)` . Within it perform the needed check and call the related business based on the message result.You call this `processAfterAjax(errMsg)` from the callback of the ajax. – KAD Oct 12 '15 at 05:54
0

You can use $.Deferred like this:

function update(field_name, field_value){
  var defObj = $.Deferred();
  if(field_value){
         $.post("/restapi/vc/users/id/${user.id}/profiles/name/"+field_name+"/set?value="+field_value, function(data, status){


               defObj.resolve(data);
          });
   }
  return defObj.promise();

}

and you can get the data attribute here

var result = update(ield_name,field_value);

$.when(result).done(function(data){
  //  ....you will get the `txt` here..
  //    ... so move your above code here..
  var xmlDoc = data;
  var x = xmlDoc.getElementsByTagName("response")[0];
  var txt = x.getAttribute("status");
  if(txt == 'error'){
        var msg = xmlDoc.getElementsByTagName("message")[0];
        var errMsg = msg.childNodes[0];
        window.errMsg = errMsg.nodeValue;
        // other code goes here...
  }

});
Sandeep Nayak
  • 4,649
  • 1
  • 22
  • 33
  • done bro :) there were some error xmlDoc not defined .. but i solved . thank you so much .. – Tariq Husain Oct 12 '15 at 06:02
  • Oh I see..In that case, you can only put `defObj.resolve(data);` inside the POST callback and do all computations below – Sandeep Nayak Oct 12 '15 at 06:03
  • in updated function i got status also and i return status and error message as json object . window.validate = {}; validate.status = false; validate.message = errMsg; defObj.resolve(validate); – Tariq Husain Oct 12 '15 at 06:04