Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: how to make ajaxSend wait for another Ajax response before proceeding?

I'm using jQuery (v.3.0.0) and I need ajaxSend() to check if a value is present in localStorage, to add it in the outgoing request headers.

If the value is not present in localStorage, ajaxSend() should get this value with another Ajax request and then send the original request with the correct value in the headers.

This must be a global handler, that applies to all jQuery Ajax requests that are sent out.

Let's make a code example.

$(document).ajaxSend(function (ev, req, opts) {
  // Before sending any jQuery Ajax request
  var original = req;
  if (localStorage.foo) {
    // If value "foo" is available, add it to the headers
    req.setRequestHeader('foo', localStorage.foo);
  } else {
    // Otherwise get it first, and add it to the headers
    $.get({url: '/foo', global: false})
      .done(function (data, textStatus, req) {
        // "foo" is received and added to the original request headers
        localStorage.foo = data;
        original.setRequestHeader('foo', data);
        // Now the original request is ready to be sent
      });
  }
});

When foo is not available, the problem with the code above is that obviously the original request is sent out before the value of foo is retrieved.

Is there any way to fix this and get it to work properly?

Thanks!!

like image 592
Pensierinmusica Avatar asked Sep 18 '25 16:09

Pensierinmusica


1 Answers

So far, this is the best solution that I could find. It's not perfect, and it does not exactly answer the original question, but it's a good workaround and gets very close to what I was trying to achieve.

The main difference is that instead of making the original request wait, it cancels it, it gets the desired value, and then it creates a new request with the same settings as the original one.

$(document).ajaxSend(function (ev, req, opts) {
  if (localStorage.foo) {
    // If value "foo" is available, add it to the headers
    req.setRequestHeader('foo', localStorage.foo);
  } else {
    // Otherwise cancel the original request, then get "foo",
    // and create a new request with the same settings as the original one
    req.abort();
    $.get({url: '/foo', global: false})
      .done(function (data, textStatus, req) {
        // "foo" is received
        localStorage.foo = data;
      })
      .then(function () {
        $.ajax(opts);
      });
  }
});

It works perfectly. If someone finds out a better solution that allows to directly use the original request I'll be happy to edit this answer and improve it.

Thanks!

like image 165
Pensierinmusica Avatar answered Sep 21 '25 05:09

Pensierinmusica