DEV Community

loading...
Cover image for Fetch vs. Axios - comparison

Fetch vs. Axios - comparison

duomly profile image Duomly Originally published at blog.duomly.com ・7 min read

This article was originally published at https://www.blog.duomly.com/fetch-vs-axios-what-is-better-in-2020/


Intro to Fetch vs. Axios

One of the most essential parts of frontend development is communication with the backend by making HTTP requests. There are a few ways how we can make API calls in Javascript asynchronously.

A few years ago, most applications were sending HTTP requests using Ajax, which stands for Asynchronous Javascript and XML. But right now, developers mostly decide about selection between fetch() API and Axios.

In this article, I’d like to compare those two methods, go through basic overview and syntax. Besides that, I’ll compare the process of converting data to JSON format in both cases and error handling as well. I’m also going to talk about HTTP interception and download progress.

Let’s start!

Fetch overview and syntax

When we are building a Javascript project, we can use a window object, and it comes with many great methods that we can use in the project. One of those features is Fetch API, which provides an easy, global .fetch() method, which is a logic solution to fetch data from the API asynchronously.

Let’s take a look at the syntax of the .fetch() method.

fetch(url)
  .then((res) => 
    // handle response
  )
  .catch((error) => {
    // handle error
  })
Enter fullscreen mode Exit fullscreen mode

In the example above, you can see the syntax of a simple fetch GET request. In .fetch() method, we have one mandatory argument url. It returns a Promise, which can resolve with the Response object.

The second argument in .fetch() method are options, and it’s optional. If we won’t pass the options the request is always GET, and it downloads the content from the given URL.

Inside the options parameter, we can pass methods or headers, so if we would like to use the POST method or any other, we have to use this optional array.

As I mentioned before, the Promise returns the Response object, and because of that, we need to use another method to get the body of the response. There are a few different methods that we can use, depends on the format of the body that we need:

  • response.json()
  • response.text()
  • response.formData()
  • response.blob()
  • response.arrayBuffer()

Let’s take a look at the code example with an optional parameter.

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
});
  .then((response) => response.json())
  .catch((error) => console.log(error))
Enter fullscreen mode Exit fullscreen mode

In the code example above, you can see the simple POST request with method, header, and body params. Then I use json() method to convert the response to JSON format.

Now, let’s take a closer look at the axios.

Axios overview and syntax

Axios is a Javascript library for making HTTP requests from Node.js or XMLHttpRequests or browser. As a modern library, it’s based on Promise API.

axios has some advantages that are like protection against XSRF or canceling requests.

To be able to use axios library, we have to install it and import it to our project. axios can be installed using CDN, npm, or bower. Now let’s take a look at the syntax of a simple GET method.

axios.get(url)
  .then(response => console.log(response));
  .catch((error) => console.log(error));
Enter fullscreen mode Exit fullscreen mode

In the code above, you can see how I user axios to create a simple GET request using .get() method. If you’d like to use the POST method in the function, then it’s enough to use .post() method instead and pass the request data as a parameter.

When we are creating a config object we can define bunch of properties, the most common are:

  • baseUrl
  • params
  • headers
  • auth
  • responseType

As a response, axios returns a promise that will resolve with the response object or an error object. In the response object, there are the following values:

  • data, which is the actual response body
  • status, HTTP status of the call, like 200 or 404
  • statusText, HTTP status returned as a text message, for example, ok
  • headers, the server sends headers back
  • config, request configuration
  • request, the XMLHttpRequest object

Right now, let’s take a look at the code example with the POST method with data.

axios.post({
  '/url', 
  { name: 'John', age: 22},
  { options }
})
Enter fullscreen mode Exit fullscreen mode

In the code above, you can see the post method, where we put the config object as a param, with URL, data, and additional options.

We can also define the config object as a variable and pass it to the axios like in the example below.

const config = {
  url: 'http://api.com',
  method: 'POST',
  header: {
    'Content-Type': 'application/json'
  },
  data: {
    name: 'John',
    age: 22
  }
}

axios(config);
Enter fullscreen mode Exit fullscreen mode

Here, you can see that all the parameters, including URL, data, or method, are in the config object, so it may be easier to define everything in one place.

JSON

As I mentioned before, when we are using .fetch() method, we need to use some kind of method on the response data, and when we are sending the body with the request, we need to stringify the data.

In axios it’s done automatically, so we just pass data in the request or get data from the response. It’s automatically stringified, so no other operations are required.

Let’s see how we can get data from fetch() and from axios.

// fetch
fetch('url')
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log(error))

// axios
axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => console.log(error))
Enter fullscreen mode Exit fullscreen mode

In the example above, you can see that with axios we don’t have an additional line of code, where we have to convert data to JSON format, and we have this line in .fetch() example.
In the case of a bigger project where you create a lot of calls, it’s more comfortable to use axios to avoid repeating the code.

Error handling

At this point, we also need to give points for axios as handling errors is pretty easy. If there will be a bad response like 404, the promise will be rejected and will return an error, so we need to catch an error, and we can check what kind of error it was, that’s it. Let’s see the code example.

axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => {
    if (error.response) {
      // When response status code is out of 2xx range 
      console.log(error.response.data)
      console.log(error.response.status)
      console.log(error.response.headers)
    } else if (error.request) {
      // When no response was recieved after request was made
      console.log(error.request)
    } else {
      // Error
      console.log(error.message)
    }
  })
Enter fullscreen mode Exit fullscreen mode

In the code above, I’ve returned data when the response was good, but if the request failed in any way, I was able to check the type of error in .catch() part and return the proper message.

With the .fetch() method, it’s a little bit more complicated. Every time we get a response from the .fetch() method, we need to check if the status is a success because even if it’s not, we will get the response. In case of .fetch() promise won’t be resolved only when the request won’t be completed. Let’s see the code example.

fetch('url')
  .then((response) => {
    if (!response.ok) {
      throw Error(response.statusText);
    }
    return response.json()
  })
  .then((data) => console.log(data))
  .catch((error) => console.log(error))
Enter fullscreen mode Exit fullscreen mode

In this code, I’ve checked the status of the code in the promise object, and if the response had status ok, then I could process and use .json() method, but if not, I had to return error inside .then().

For easy and proper error handling, axios will be definitely a better solution for your project, but still, if you are building a small project with one or two requests, it’s fine to use .fetch(), but you need to remember to handle errors correctly.

Download progress

When we have to download a large amount of data, a way to follow the progress would be useful, especially when users have slow internet. Earlier, to implement progress indicators developers used XMLHttpRequest.onprogress callback. In .fetch() and axios, there are different ways to do it.

To track progress of download in .fetch() we can use one of the response.body properties, a ReadableStream object. It provides body data chunk by chunk, and it allows us to count how much data is consumed in time.

In axios, implementing a progress indicator is possible as well, and it’s even easier because there exists a ready module, which can be installed and implemented; it’s called Axios Progress Bar.

If you have a lot of large data to download and you want to track the progress in progress indicator, you can manage that easier and faster with axios but .fetch() gives the possibility as well, just it needs more code to be developed for the same result.

HTTP interception

HTTP interception can be important when we need to check or change our HTTP requests from the application to the server, or in the other way, for example, for authentication.

In the case of axios HTTP interception is one of the key features of this library, that’s why we don’t have to create additional code to use it. Let’s take a look at the code example to see how easy we can do it.

// request interceptor
axios.interceptors.request.use((config) => {
  console.log('Request sent');
})

// response interceptor
axios.interceptors.response.use((response) => {
  // do an operation on response
  return response
})

axios.get('url')
  .then((response) => console.log(response))
  .catch((error) => console.log(error))
Enter fullscreen mode Exit fullscreen mode

In the code, you can see the request interception and response interception. In the first case, I created a console.log informing about sending requests, and in the response interception, we can do any action on response and then return it.

.fetch() doesn’t provide the HTTP interception by default, there’s a possibility to overwrite the .fetch() method and define what needs to happen during sending the request, but of course, it will take more code and can be more complicated than using axios functionality.

Conclusion

In this article, I compare two methods used for creating HTTP requests, starting for a simple overview, through syntax and some important features like download progress or error handling.

This comparison shows that Axios is a better solution in case of an application where there are a lot of HTTP requests which needs a good error handling or HTTP interceptions. In the case of small projects, with just a few simple API calls, Fetch can be a good solution as well.

It’s very important to pay attention to one more factor when choosing the best solution for your project. Axios is supported by most browsers and the Node.JS environment as well when Fetch is supported just by modern browsers and may have some issued with the older ones.

With this knowledge, I hope you are able to select the best solution for you, and you find this comparison helpful.

Duomly - Programming Online Courses

Thank you for reading,
Anna

Discussion

pic
Editor guide
Collapse
shaijut profile image
Shaiju T

Nice, 😄, I read your article first time. Because you wrote to the point, I was able to read it fast. So I am taking home below points:

  • Axios has more features than fetch can be used in large projects to avoid duplicate code. This will help to keep large projects more maintainable.
  • Fetch has less features than Axios can be used in small projects.

Good write up. Thanks :)

Collapse
sebbdk profile image
Sebastian Vargr

We are comparing a library to a native browser method, it seems kinda like comparing an apple to an apple-tree to me. Is this comparison valid?

In a performance-based world, the native method always wins out because of the library weight.

As for interceptors, consider using a service-worker for that kind of operation.
Or, wrap your fetch method, in an "interceptedFetch" method.

Also, there are no async examples here. Fetch is soooo' much more fun and verbose to use when coupled with async functions.

async function getTheThings() {
  try {
    const request = await fetch('....my-url.json', ...);
    const data = await request.json();

   // ...do something with data, return, format etc.
  } catch(e) {
  // handle error
  // or throw a new custom that the callee can be setup to handle
  }
}
Enter fullscreen mode Exit fullscreen mode

All promises work interchangeably with async. :)
And you only need the expensive polyfills if you support legacy browsers.

Collapse
michaelcurrin profile image
Mike

Note that while fetch is standard in modern browsers, it is not in Node. So if you have to run any fetch commands on your backend or you want your code processing to not complain that it doesn't understand fetch on your frontend JS... then install a drop-in replacement like

npm i node-fetch

The NPM readme for that package covers it well

npmjs.com/package/node-fetch#motiv...

Also i would not say that Ajax has gone away like you suggest. Ajax is a concept of non-blocking (asynchronous) requests and fetch, axios etc. are tools to achieve that.

BTW request is another popular library you could do a follow up post on. And jQuery also has $.ajax(url) and $.json(url) and other methods which handle the requests library for you.

Collapse
shaijut profile image
Shaiju T

I just came to know by looking axios github repo, that axios is heavily inspired by the $http service provided in Angular. One project has inspired another standalone project. :)

Collapse
alirezavalizade profile image
alireza valizade

Would be nice to address the way of adding params to fetch since I had issue with it couple of days ago. This is what I use.

const api = (props) => {
  const { url, params = {}, ...rest } = props;
  const parsedURL = new URL(`${process.env.BASE_URL}${url}`);
  const paramsKeys = Object.keys(params);
  if (paramsKeys.length) {
    paramsKeys.forEach((key) => {
      if (params[key]) {
        parsedURL.searchParams.append(key, params[key]);
      }
    });
  }
  return fetch(parsedURL, {
    ...rest
  }).then((res) => res.json());
};

export default api;
Enter fullscreen mode Exit fullscreen mode
Collapse
_danieldev profile image
Daniel Michael 👨‍💻

Also I think people should start using try catch instead of .then and .catch

Collapse
michaelcurrin profile image
Mike

.catch is needed to work with promises to get the expected flow.

You can use try catch but then you need to use the async function syntax. See code samples here.

dev.to/annarankin/finally-in-promi...

Collapse
_danieldev profile image
Daniel Michael 👨‍💻

Thanks for this, I use axios and kept seeing fetch and had no idea what it meant.

Collapse
alqusi1992 profile image
alqusi1992

Thank u very much for useful article that give me an overview about those Tools.

Collapse
adilvelizade0 profile image
Adil Velizade

Pls We support our friend on Instagram : @master_javascript