Fetch vs Axios: Key Differences and Use Cases
Tags: javascript, webdev, react, angular
Published: 2024-07-04 06:10:12

When building web applications, making HTTP requests is a fundamental task. Two popular methods for making these requests in JavaScript are the fetch API and the Axios library. This guide will compare fetch and Axios, highlighting their differences, strengths, and weaknesses.

## Overview of Fetch and Axios

### Fetch API:

- **Built-in**: The fetch API is a modern, built-in JavaScript API for making network requests. It is part of the global window object in the browser and does not require any additional libraries, also with the recent release of NodeJS v17.0, it was added as an experimental feature and it now comes bundled with the latest LTS.
- **Promise-based**: It returns promises, which makes it easier to work with asynchronous requests compared to older techniques like XMLHttpRequest.

### Axios:

- **Third-party library**: Axios is a promise-based HTTP client for JavaScript, which can be used in both the browser and Node.js.
- **Feature-rich**: Axios comes with a rich set of features out of the box, simplifying many tasks that require more effort with fetch.

---

## Key Differences Between Fetch and Axios

### 1. Syntax and Simplicity: 
Axios provides a cleaner and more concise syntax, especially for handling JSON responses and errors.

- **Fetch:**

```
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
```

- **Axios:**
```
axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));
```

---

### 2. Error Handling:

- **Fetch:** Only rejects a promise if a network error occurs. For other types of errors (e.g., HTTP status codes like 404 or 500), you need to manually check the response.ok property.
```
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
```

- **Axios**: Automatically rejects the promise for any HTTP status code outside the range of 2xx.
```
axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));
```

---

### 3. Request and Response Interceptors:

- **Fetch**: Does not support interceptors natively. You would need to manually handle this logic.
- **Axios**: Supports request and response interceptors, allowing you to modify requests or handle responses globally.

```
axios.interceptors.request.use(config => {
  // Modify config before request is sent
  return config;
}, error => {
  return Promise.reject(error);
});

axios.interceptors.response.use(response => {
  // Modify response before handling it
  return response;
}, error => {
  return Promise.reject(error);
});
```

---

### 4. Default Timeout:

- **Fetch**: Does not have a built-in timeout feature. You need to implement it manually using AbortController.
```
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);

fetch('https://api.example.com/data', { signal: controller.signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.error('Fetch request timed out');
    } else {
      console.error('Fetch error:', error);
    }
  });
```
- **Axios**: Supports setting a default timeout.
```
axios.get('https://api.example.com/data', { timeout: 5000 })
  .then(response => console.log(response.data))
  .catch(error => {
    if (error.code === 'ECONNABORTED') {
      console.error('Axios request timed out');
    } else {
      console.error('Axios error:', error);
    }
  });

```

---

### 5. Automatic JSON Transformation:

- **Fetch**: Requires manual transformation of JSON responses.

```
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data));

```

- **Axios**: Automatically transforms JSON responses.

```
axios.get('https://api.example.com/data')
  .then(response => console.log(response.data));
```

---

6. Handling Query Parameters

- **Fetch**: You need to manually append query parameters to the URL.

```
const params = new URLSearchParams({ key1: 'value1', key2: 'value2' });
fetch(`https://api.example.com/data?${params.toString()}`)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
```

- **Axios**: Axios has built-in support for query parameters.

```
axios.get('https://api.example.com/data', {
  params: {
    key1: 'value1',
    key2: 'value2'
  }
})
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));
```

---

## Conclusion
Both fetch and Axios are powerful tools for making HTTP requests in JavaScript, each with its own strengths and weaknesses.

**Use Fetch if:**
- You prefer using a built-in API without additional dependencies.
- Your project needs to stay lightweight.
- You are comfortable handling JSON transformation and error checking manually.

**Use Axios if:**
- You need a cleaner syntax and more readable code.
- You want built-in support for request and response interceptors, timeout, and cancellation.
- You prefer automatic JSON transformation and simpler error handling.

Ultimately, the choice between fetch and Axios depends on your project's requirements and your personal or team's preferences. Both can effectively handle HTTP requests, but Axios offers more features and convenience, while fetch provides a more native and minimalistic approach.