javascriptasync-awaitfetchsetintervalabort

How to Restart fetch api request after aborting using AbortController


I am working on order taking an application for takeaways (using WooCommerce API) where order will receive instantly. I created a simple dashboard where all orders displayed and get new order using fetch API with setInterval.

so when user clicks on order they receive on dashboard. A Model pop appears where user manages the order. But because of setInterval (for 5s) the Model disappears. To solve of this problem, I use the technique to clear the interval so when user clicks on an order interval is cleared and won't request further until user manage order on the Model box and press save button, on save I call setInterval function again.

But in this technique, there is an issue: if setInterval is going to execute and user clicks on order and because fetch is already fired and all orders refreshed, the Model disappears. So I have to click order again.

So then I use AbortController API, it works exactly as I want.

AbortController to abort async fetch request, once I aborted the fetch request it won't start again and instead of giving error telling operation aborted (Uncaught (in promise) DOMException: The operation was aborted).

So long story short, how can I restart a fetch API request again with using AbortController?

const controller = new AbortController();
const signal = controller.signal;

function gettingOrders(){

var refreshInterval = setInterval(async function(){

const response = await fetch('index.php',{
    method: "GET",
    signal: signal,
    headers : { 
      'Content-Type': 'text/html',
      'Accept': 'text/html'
   }});
   try {

    const html = await response.text();
    var parser = new DOMParser();
    var doc = parser.parseFromString(html, "text/html");
    var div = doc.getElementById('newOrder').innerHTML;
    document.getElementById('newOrder').innerHTML = div;
   }
   catch(err) {
    console.log('error: ', err);
  }
     
  }, 5000);
  }

  gettingOrders();

  var sinterval = refreshInterval;
  sessionStorage.setItem("sinterval", sinterval);

  function abortFetching() {
  console.log('Now aborting');
  controller.abort();
  }

Solution

  • AbortController is consumed once aborted. You have to create new instance each call. Example code:

    let controller;
    let refreshInterval;
    
    function getOrders(){
      refreshInterval = setInterval(async function() {
        controller = new AbortController();
        const signal = controller.signal;
        try {
          const response = await fetch('index.php',{
            method: "GET",
            signal: signal,
            headers : { 
              'Content-Type': 'text/html',
              'Accept': 'text/html'
            }
          });
          const html = await response.text();
          var parser = new DOMParser();
          var doc = parser.parseFromString(html, "text/html");
          var div = doc.getElementById('newOrder').innerHTML;
          document.getElementById('newOrder').innerHTML = div;
        }
        catch(err) {
          console.log('error: ', err);
        }
      }, 5000);
    }
    
    function abortFetching() {
      console.log('Now aborting');
      clearInterval(refreshInterval); // else it aborts only current fetch
      controller.abort();
    }
    
    getOrders();
    
    const sinterval = refreshInterval;
    sessionStorage.setItem("sinterval", sinterval);