Fil Fil - 6 months ago 11
Javascript Question

How to call a method of a javascript object inside ajax

Given this code,

var submit = {
send:function (form_id) {
var url = $(form_id).attr("action");
$.ajax({
type: "POST",
url: url,
data: $(form_id).serialize(),
dataType: 'json',
success: function(result) {
this.ret(result.message);
},
error: function(result) {
// Some error message
}
});
},

ret:function (result) {
this.result_data = result;
},

result_data:""
};


will send a data from the form to a controller which if will return a json

$result['message'] = validation_errors();
echo json_encode($result);


I try to call this javascript object in this code,

var res = submit.send(form_id);


wherein
form_id
is the form
id
, and look for the output using

console.log(res);


In the console, it shows
undefined
. After searching for an explaination using google and stackoverflow itself I got the idea that,

this.ret(result.message);


is being called inside ajax which is another object, indicating that it's not part of it's method.

My problem is, how to call the method
ret()
inside ajax?

Is anyone can explain it to me?

Answer

There is several ways to deal with it.

One is ES5 compatible (and this is actually quite common pattern):

var submit = {
send: function (form_id) {
  var url = $(form_id).attr("action");
  var self = this; // << this is binded to self varialble
  $.ajax({
    type: "POST",
    url: url,
    data: $(form_id).serialize(),
    dataType: 'json',
    success: function(result) {
      self.ret(result.message); // << replaced this to self so it has all the methods from the submit object.
    },
    error: function(result) {
      // Some error message
    }
  });
}),

ret:function (result) {
  this.result_data = result;
},

result_data:""
};

And another is using arrow function from ES2015:

var submit = {
send: function (form_id) {
  var url = $(form_id).attr("action");
  $.ajax({
    type: "POST",
    url: url,
    data: $(form_id).serialize(),
    dataType: 'json',
    success: (result) => {
      this.ret(result.message); // << arrow function is called in context of the parent function, so no needs to change anything.
    },
    error: function(result) {
      // Some error message
    }
  });
}),

ret:function (result) {
  this.result_data = result;
},

result_data:""
};

Explanation: context of this in callback function will be bind to global scope not to the object's one. So you need somehow to change it.

You can also use bind or put success as a object method. As it mentioned in other answers. Same thing, you want to keep this to be object's context.

There is a good article about this in javascript.