<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cakra Danu Sedayu</title>
    <description>The latest articles on DEV Community by Cakra Danu Sedayu (@cakrads).</description>
    <link>https://dev.to/cakrads</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F374268%2F411d8345-5920-461d-99b1-8aca3a1adfbc.png</url>
      <title>DEV Community: Cakra Danu Sedayu</title>
      <link>https://dev.to/cakrads</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cakrads"/>
    <language>en</language>
    <item>
      <title>Cancel HTTP Request by Using AbortController in Web App</title>
      <dc:creator>Cakra Danu Sedayu</dc:creator>
      <pubDate>Sun, 08 Jan 2023 16:05:22 +0000</pubDate>
      <link>https://dev.to/cakrads/cancel-http-request-by-using-abortcontroller-in-web-app-16di</link>
      <guid>https://dev.to/cakrads/cancel-http-request-by-using-abortcontroller-in-web-app-16di</guid>
      <description>&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;p&gt;In a simple way, it is to optimize our Website Performance by controlling ongoing HTTP requests, for example, users leave the page when a HTTP request is running, users want to stop their download/upload file, and many more depending on your app. So, this article may help you or me (in the future) to understand and know how to &lt;code&gt;Cancel&lt;/code&gt; our HTTP Request with &lt;code&gt;AbortController&lt;/code&gt; in a web Application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abort Controller?
&lt;/h3&gt;

&lt;p&gt;According to MDN:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The AbortController interface represents a controller object that allows you to abort one or more Web requests as and when desired.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;AbortController&lt;/code&gt; is a Class that has one &lt;code&gt;instance properties&lt;/code&gt; and one &lt;code&gt;instance methods&lt;/code&gt;, the instance property is &lt;code&gt;signal&lt;/code&gt; and the instance method is &lt;code&gt;abort&lt;/code&gt;. The &lt;code&gt;AbortController&lt;/code&gt; is supported in almost all browsers except IE (but, who cares -_-). &lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Here simple explanation how to use it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// declare 
const controller = new AbortController();

// get signal
const signal = controller.signal;

// put signal in fetch or axios options
fetch(API, { signal });
axios(API, { signal });

// cancel request
controller.abort();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Cancel fetch in HTTP Request
&lt;/h4&gt;

&lt;p&gt;In case we have a feature that can download a BIG file. To make it user-friendly, we should provide a &lt;code&gt;cancel button&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let controller;

const abortBtn = document.querySelector(".abort");

abortBtn.addEventListener("click", () =&amp;gt; {
  if (controller) {
    controller.abort();
    console.log("Download aborted");

    // Reset new AbortController, so we can do re-fetch
    controller = new AbortController();
  }
});

function fetchVideo() {
  controller = new AbortController();
  const signal = controller.signal;

  fetch(url, { signal })
    .then((response) =&amp;gt; {
      console.log("Download complete", response);
    })
    .catch((err) =&amp;gt; {
      if (err.name === 'AbortError') {
        console.log('successfully aborted');
      } else {
        // handle error
      }
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Cancel Request when useEffect Clean Up
&lt;/h4&gt;

&lt;p&gt;The most popular AbortController usage is to clean up the useEffect function in react.js. FYI, starting from &lt;code&gt;v0.22.0&lt;/code&gt; Axios supports AbortController to cancel requests, and &lt;code&gt;CancelToken&lt;/code&gt; is deprecated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const controller = new AbortController();
  const source = controller.signal;

  axios
    .get(API, { signal })
    .catch((err) =&amp;gt; {
      if (error.name === "CanceledError") {
        console.log('successfully aborted');
      } else {
        // handle error
      }
    });
  return () =&amp;gt; {
    // cancel the request before component unmounts
    source.cancel();
  };
}, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the important thing is, errName in axios is &lt;code&gt;CanceledError&lt;/code&gt; and in fetch is &lt;code&gt;AbortError&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cancel fetch Request in TypeScript react.js
&lt;/h4&gt;

&lt;p&gt;this example is not really different from the first example, but sometimes we can adopt 100% js code to react.js code. And in TypeScript, sometimes, it makes more challenging to use the correct type in, what should type I use, where to find the docs, etc (:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useRef } from "react";

function Component() {
  const abortControllerRef = useRef&amp;lt;AbortController&amp;gt;(new AbortController());

  const onAbortFetch = () =&amp;gt; {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      console.log("Download aborted");

      // Reset new AbortController, so we can do re-fetch
      abortControllerRef.current = new AbortController();
    }
  };

  function getFile() {
    const signal = abortControllerRef.current.signal;

    fetch(API, { signal })
      .then((response) =&amp;gt; {
        console.log("Download complete", response);
      })
      .catch((err) =&amp;gt; {
        if (err.name === "AbortError") {
          console.log("successfully aborted");
        } else {
          // handle error
        }
      });
  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button onClick={getFile}&amp;gt;Get File&amp;lt;/button&amp;gt;
      &amp;lt;br /&amp;gt;
      &amp;lt;br /&amp;gt;
      &amp;lt;button onClick={onAbortFetch}&amp;gt;Abort&amp;lt;/button&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

export default Component;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;a href="https://gist.github.com/cakrads/9123120f8a265f1d39451f3f1105d94b"&gt;gist link &lt;/a&gt;, I'm not embed here cause the gist preview only show one line only.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;An instance of the &lt;code&gt;AbortController&lt;/code&gt; class exposes the &lt;code&gt;abort&lt;/code&gt; method and the &lt;code&gt;signal&lt;/code&gt; property. Put the signal in options of &lt;code&gt;fetch&lt;/code&gt; or &lt;code&gt;axios&lt;/code&gt; then called the abort method whenever you want to cancel the HTTP request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController"&gt;MDN AbortController&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>axios</category>
      <category>abortcontroller</category>
    </item>
  </channel>
</rss>
