Marcin
Marcin

Reputation: 35

Intercept fetch() request, put it on-hold and resume when certain criteria is met

The following code fires an alert when it detects fetch() request to a certain endpoint. Doing so makes the request stops from proceeding, waits for the user to close the alert and then lets the request flow to the endpoint.

My question is how to achieve the same interruption, but instead of waiting for the alert to be closed, I'd need the request to wait for the appearance of a cookie. I have a feeling it needs to be done with Promises :)

const x = window.fetch;
window.fetch = function() {
   if (arguments[0] == '/certain_endpoint') { alert('stopping for a while'); }
   return x.apply(this, arguments)
}

Upvotes: 1

Views: 1703

Answers (2)

Eric
Eric

Reputation: 1521

You can use setInterval with promises to periodically poll for a certain condition and resolve when it is met.

const x = window.fetch;
window.fetch = function() {
  if (arguments[0] == '/needs_cookie') {
    return waitForCookie().then(cookie => {
      return x.apply(this, arguments);
    });
  } else {
    return x.apply(this, arguments);
  }
}

// Returns a promise that resolves to a cookie when it is set.
function waitForCookie() {
  return new Promise(function (resolve, reject) {
    var intervalID = setInterval(checkForCookie, 100);
    function checkForCookie() {
      var cookie = getCookie();
      if (cookie) {
        clearInterval(intervalID);
        resolve(cookie);
      }
    }
  });
}

// Here, getCookie() returns undefined the first two times it's called.
// In reality, it should just parse document.cookie however you normally do.
var attempts = 0;
function getCookie() {
  if (attempts < 2) {
    attempts++;
    console.log('Attempts: ', attempts);
    return undefined;
  } else {
    return 'cookie!';
  }
}

If you're trying to do more complicated asynchronous stuff, including polling, you may want to check out RxJS.

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138257

{
  const original = window.fetch
  window.fetch = function(...args) {
    if (args[0] == '/certain_endpoint') { 
       return new Promise(res => {
         setTimeout(() => res(original(...args)), 1000);
       });
     }
     return original(...args);
  };
 }

You may return a promise instead that resolves after some time

Upvotes: 0

Related Questions