skip to Main Content

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) Model disappear, to solve of this problem, I use the technique to clear interval so when user clicks on an order interval 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 click on order and because fetch is already fired and all orders refreshed, Model Disappear. so I have to click order again (see picture) https://postimg.cc/H8267CGd

so then I use AbortController Api, it works exactly as i want.

AbortController to abort async fetch request, once i aborted 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 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();
  }

2

Answers


  1. 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);
    
    Login or Signup to reply.
  2. I solved this issue in React Like below:

    import React, { useState, useEffect } from 'react';
    import './style.css';
    import axios from 'axios';
    let abortController = new AbortController();
    export default function App() {
     const [isCancel, setIsCancel] = useState(false);
    
     useEffect(() => {
     isCancel && abortController.abort();
     }, [isCancel]);
    
    const onStart = () => {
     try {
      setIsCancel(false);
       abortController = new AbortController();
       axios
        .get('https://api.github.com/users', { signal: abortController.signal })
        .then((res) => console.log(res.status))
        .catch((err) => console.log(err));
    } catch (er) {
      console.log(er);
    }
    };
    
    return (
    <div>
      <button onClick={onStart}>Start</button>
      <button onClick={() => setIsCancel(true)}>Cancel</button>
    </div>
    );
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search