1

I've got code in the following structure. The intent is to send an Ajax request, and to retry it some number of times with a delay between each try:

$.ajax({
  type: 'GET',
  url: 'https://example.com',
  retryLimit: 3,
  attempt: 1,
  success: function (data) {
    doStuff();
  },
  error: function (data) {
    if (this.attempt++ <= this.retryLimit) {
      var retry = function () {
        $.ajax(this);
      };
      setTimeout(retry, 1000);
    } else {
      handleError();
    }
  }
});

The problem is that I'm getting a TypeError: Illegal invocation when trying to call $.ajax. I also attempted to replace with promises, like this:

new Promise(function(resolve) {
  setTimeout(resolve, 1000);
}).then(function() {
  $.ajax(this);
});

But I got the same error. What is going on, and how can I resolve it?

NOTE: I'm using the Atlassian SDK to build a Jira plugin, so my javascript version seems to be limited. I'm not 100% sure which version I have, but I know it fails to compile when I try to use arrow functions.

ewok
  • 20,148
  • 51
  • 149
  • 254
  • 2
    What is `this` when the retry is attempted? It sounds like you may need to store it in a variable for the closure. Something like: `var self = this; var retry = function () { $.ajax(self); }` – David Dec 14 '18 at 16:14
  • 1
    exactly that - or use an arrow function for `retry` – Robin Zigmond Dec 14 '18 at 16:14

1 Answers1

3

The context of this has changed by the time that retry() function executes, and is no longer the AJAX info. You should, however, be able to wrap it in a closure by using a variable:

var self = this;
var retry = function () {
    $.ajax(self);
};

(Note that this whole context is itself also happening in a callback, error. So if this still isn't what you need it to be, you may need to apply this same concept another scope higher.)

David
  • 208,112
  • 36
  • 198
  • 279
  • so [this](https://pastebin.com/dPrRfdwq) worked. Why did `this` change in the scope of the `retry` function, but _not_ in the scope of the `error` argument? – ewok Dec 14 '18 at 16:23
  • 1
    @ewok: It's possible to specify the context of `this` when binding a function, jQuery may be doing that for you in the callbacks to `$.ajax()`. – David Dec 14 '18 at 16:24