mytom
mytom

Reputation: 105

How retrieve results after asynchronous function?

I've read posts on asynchronous calls and callbacks but i did not find my answer.

i've a simple dropdown button on my boostrap page, who let users change values. So when button is clicked, i call an ajax function to do the job, and we must wait for result of the action.

After that, i want to change dropdown button value and give the result of the operation to the user.

So this is my callback function with ajax (which works great) :

function changePermissions(user, role, callBack){
  var ret = false;
  $.ajax({
    url: "lib/edit_permissions.php",
    data: {'user': user, 'role': role},
    type: 'post',
    dataType: 'json',
    success: function(data) {
      if($.isPlainObject(data) && data.state === 200){
        ret = true;
      }
      else {
        console.log(data.message);
      }
      return callBack( ret );
    },
    error: function (xhr, ajaxOptions, thrownError) {
      console.log("thrown error");
      return callBack( ret );
    }
  });
}

If i try to retrieve the result outside the function, the value is undefined, i understand that it is an asynchronous problem:

$(".dropdown-menu li a").click(function(){
var newrole = $(this).text();

var result=false;
result = changePermissions(user, newrole, function(ret) {
           return ret;
         });
}

if (result){
  $(this).parents(".dropdown").find('.btn').html(newrole + ' <span class="caret"></span>');
  console.log("permissions successfully updated.");
}
else {
  console.log("Error to update permissions");
}

If i try to retrieve the result inside the function, the result is OK. But i can't update my button text value, '$this' seems to be undefined:

$(".dropdown-menu li a").click(function(){
  var newrole = $(this).text();
  var user = $(this).parents(".dropdown").closest('td').prev('td').text();

  changePermissions(user, newrole, function(ret) {
    if (ret){
      $(this).parents(".dropdown").find('.btn').html(newrole + ' <span class="caret"></span>');
      console.log("user permissions successfully updated.");
    }
    else{
      console.log("error to update");
    }
  });
});

How can i do that ?

Upvotes: 0

Views: 57

Answers (1)

Jimish Fotariya
Jimish Fotariya

Reputation: 1097

That is normal because, this inside callback doesn't refers to DOM object or target of the event. It overrides. To use it, you need to create a local copy of that and to use that copy inside callback. Here is code.

$(".dropdown-menu li a").click(function(){
  var newrole = $(this).text();
  var user = $(this).parents(".dropdown").closest('td').prev('td').text();

  //make copy of this 
var self = this;
  changePermissions(user, newrole, function(ret) {
    if (ret){
     //use that copy
      $(self).parents(".dropdown").find('.btn').html(newrole + ' <span class="caret"></span>');
      console.log("user permissions successfully updated.");
    }
    else{
      console.log("error to update");
    }
  });
});

Upvotes: 1

Related Questions