最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to call a method of a javascript object inside ajax - Stack Overflow

programmeradmin1浏览0评论

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?

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?

Share Improve this question asked May 14, 2016 at 3:53 FilFil 8,89317 gold badges63 silver badges89 bronze badges 2
  • Yes but it return undefined when looking using console – Fil Commented May 14, 2016 at 4:13
  • @ brett dewoody: Is this possible, it needs a function, or am I wrong? – dec Commented May 14, 2016 at 4:19
Add a ment  | 

5 Answers 5

Reset to default 2

There is several ways to deal with it.

One is ES5 patible (and this is actually quite mon 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 plus deferred object returned by $.ajax:

var submit = {
send: function (form_id) {
  var url = $(form_id).attr("action");
  $.ajax({
    type: "POST",
    url: url,
    data: $(form_id).serialize(),
    dataType: 'json'
  })
  .then((result) => {
    this.ret(result.message); // << arrow function is called in context of the parent function, so no needs to change anything.
  })
  .fail(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 actually match and mix these two methods.

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.

You've two options.

1. The "bind()" method (remended)

The method bind is for changing the context of a function. From the docs:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

Here the bind will change the context of success function with the reference of this i.e. the submit.

$.ajax({
  type: "POST",
  url: url,
  data: $(form_id).serialize(),
  dataType: 'json',
  success: function(result) {
    this.ret(result.message);
  }.bind(this),                  // <== bind method
  error: function(result) {
    // Some error message
  }
});

That .bind(this) can also be written as .bind(submit);

2. Using the scope variable

Since you already have access to the submit variable, why not directly call with submit instead of this

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

In the above block the this refers to the function you are operating in. To use ret method you should use it submit.ret.

I have a small code fragment, that simulates this:

var submit = {
  send:function (form_id) {
    var self = this;
    setTimeout(function()
    { 
      console.log('send', this);
      self.ret('message'); //will do
      //submit.ret('message'); //will do
        //this.ret('message'); this.ret is not a function
      //ret('message'); ret is not defined
    }, 0);    
  },

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

  result_data:""
};

There you can see your possible choices to handle this.

Or use this fiddle: https://jsfiddle/syqjwk2q/#&togetherjs=mpwEnNDeIJ

In the submit define

self = this

And then use ret() with self: self.ret()

发布评论

评论列表(0)

  1. 暂无评论