JavaScript logoJavaScriptv1INTERMEDIATE

Axios

Axios cheat sheet covering HTTP requests, interceptors, error handling, request cancellation, and TypeScript configuration examples.

5 min read
axioshttpapiajaxfetchrequestspromisesinterceptorsjavascriptnodejs

New to Async JavaScript? Start Here First!

This sheet covers the Fetch API for making HTTP requests. If you're new to promises, async/await, or asynchronous JavaScript patterns, we recommend starting with our async JavaScript fundamentals sheet first.

Start with Async JavaScript Fundamentals
Loading your progress

Installation & Basic Requests

Install Axios and create your first request

javascript
# Install via npm
npm install axios

# Install via yarn
yarn add axios

# Install via pnpm
pnpm add axios
✅ Works in both browser and Node.js environments (isomorphic)
💡 Automatically transforms JSON data unlike fetch API
🔍 Returns full response object with data, status, headers
⚡ Promise-based with async/await support out of the box
installationsetupimport

Perform GET, POST, PUT, PATCH, and DELETE requests

javascript
// GET request
const users = await axios.get('/api/users');

// POST request with data
const newUser = await axios.post('/api/users', {
  name: 'John Doe',
  email: 'john@example.com'
});

// PUT request (full update)
const updated = await axios.put('/api/users/1', {
  name: 'Jane Doe',
  email: 'jane@example.com'
});

// PATCH request (partial update)
const patched = await axios.patch('/api/users/1', {
  email: 'newemail@example.com'
});

// DELETE request
await axios.delete('/api/users/1');
✅ Dedicated methods for each HTTP verb for cleaner syntax
💡 postForm/putForm/patchForm auto-set multipart/form-data
🔍 Second parameter is data, third is config for POST/PUT/PATCH
⚡ Use Promise.all() for concurrent requests to improve speed
getpostputpatchdeletemethods

Configure timeout, headers, query params, and more

javascript
// Basic config options
const response = await axios.get('/api/users', {
  params: { page: 1, limit: 10 },
  timeout: 5000,
  headers: {
    'Authorization': 'Bearer token123',
    'Custom-Header': 'value'
  }
});

// Base URL and default config
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: { 'X-Custom-Header': 'value' }
});

// Use custom instance
const users = await api.get('/users');
✅ Create instances with axios.create() for reusable config
💡 Use params object for query strings - auto URL-encoded
🔍 timeout applies to both connection and response time
⚡ Set baseURL once, use relative paths in all requests
configtimeoutheadersparamsbaseurl

Interceptors & Error Handling

Modify requests before they are sent

javascript
// Add request interceptor
axios.interceptors.request.use(
  (config) => {
    // Modify config before request is sent
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = \`Bearer \${token}\`;
    }
    console.log('Request:', config.method, config.url);
    return config;
  },
  (error) => {
    // Handle request error
    return Promise.reject(error);
  }
);
✅ Perfect for adding auth tokens to every request globally
💡 Multiple interceptors execute in the order they were added
🔍 Must return config object or Promise for request to proceed
⚡ Use eject() to remove interceptor if no longer needed
interceptorsrequestmiddlewareauth

Transform responses and handle errors globally

javascript
// Add response interceptor
axios.interceptors.response.use(
  (response) => {
    // Transform successful response
    console.log('Response:', response.status);
    return response.data; // Return only data
  },
  (error) => {
    // Handle error globally
    if (error.response?.status === 401) {
      // Redirect to login
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);
✅ Centralize error handling - no try/catch in every component
💡 Implement token refresh logic to handle expired sessions
🔍 Return response to continue, reject to trigger catch block
⚡ Use _retry flag to prevent infinite retry loops
interceptorsresponseerrorsretry

Error Handling

Handle and diagnose different error types

javascript
// Comprehensive error handling
try {
  const response = await axios.get('/api/data');
  console.log(response.data);
} catch (error) {
  if (axios.isAxiosError(error)) {
    if (error.response) {
      // Server responded with error status
      console.log('Data:', error.response.data);
      console.log('Status:', error.response.status);
      console.log('Headers:', error.response.headers);
    } else if (error.request) {
      // Request made but no response
      console.log('No response:', error.request);
    } else {
      // Request setup error
      console.log('Error:', error.message);
    }
  } else {
    console.log('Non-Axios error:', error);
  }
}
✅ Use axios.isAxiosError() to safely type-check error objects
💡 Check error.response first, then error.request, then error.message
🔍 error.response means server responded, request means network issue
⚡ Implement retry logic for network errors and 5xx status codes
errorserror-handlingtry-catchdebugging

Request Cancellation & Timeout

Cancel in-flight requests using modern AbortController API

javascript
// Cancel a request
const controller = new AbortController();

axios.get('/api/users', {
  signal: controller.signal
}).catch(error => {
  if (axios.isCancel(error)) {
    console.log('Request cancelled:', error.message);
  }
});

// Cancel the request
controller.abort();
✅ AbortController is the modern standard for request cancellation
💡 Essential for search inputs to cancel outdated requests
🔍 Always cleanup controllers in useEffect/componentWillUnmount
⚡ Prevents race conditions when user types quickly in search
cancelabortabortcontrollercleanup

Set connection and response timeouts to prevent hanging

javascript
// Request timeout (5 seconds)
const response = await axios.get('/api/data', {
  timeout: 5000
});

// Different timeouts per instance
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000 // 10 seconds default
});

// Override instance timeout
const quick = await api.get('/fast', { timeout: 2000 });
const slow = await api.get('/slow', { timeout: 30000 });
✅ timeout applies to entire request - both connection and response
💡 Implement exponential backoff when retrying timeout errors
🔍 Use error.code === "ECONNABORTED" to detect timeout errors
⚡ Set different timeouts for fast/slow endpoints to optimize UX
timeoutretrybackoffperformance

Advanced Patterns

Type-safe API calls with TypeScript generics

typescript
// Define response types
interface User {
  id: number;
  name: string;
  email: string;
}

interface ApiResponse<T> {
  data: T;
  message: string;
  status: number;
}

// Type-safe request
const response = await axios.get<User[]>('/api/users');
const users: User[] = response.data;

// Custom API client
const api = axios.create({
  baseURL: 'https://api.example.com'
});

async function getUsers(): Promise<User[]> {
  const { data } = await api.get<User[]>('/users');
  return data;
}
✅ Use generics to type response.data for full type safety
💡 Create wrapper class to encapsulate API logic and types
🔍 axios.isAxiosError<T> provides type-safe error handling
⚡ Define response interfaces once, reuse across all endpoints
typescripttypesgenericstype-safety

Handle file uploads with progress and file downloads

javascript
// File upload
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'Document');

const response = await axios.post('/api/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  },
  onUploadProgress: (progressEvent) => {
    const percent = Math.round(
      (progressEvent.loaded * 100) / progressEvent.total
    );
    console.log(\`Upload: \${percent}%\`);
  }
});
✅ Use responseType: "blob" for file downloads to handle binary
💡 onUploadProgress and onDownloadProgress track transfer progress
🔍 FormData auto-sets Content-Type with proper boundary
⚡ Implement chunked uploads for files larger than 100MB
uploaddownloadfilesformdataprogress

Implement JWT refresh, bearer tokens, and auth interceptors

typescript
// Bearer token authentication
const api = axios.create({
  baseURL: 'https://api.example.com'
});

api.interceptors.request.use((config) => {
  const token = localStorage.getItem('accessToken');
  if (token) {
    config.headers.Authorization = \`Bearer \${token}\`;
  }
  return config;
});

// Token refresh on 401
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;

    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;

      const refreshToken = localStorage.getItem('refreshToken');
      const { data } = await axios.post('/auth/refresh', {
        refreshToken
      });

      localStorage.setItem('accessToken', data.accessToken);
      originalRequest.headers.Authorization = \`Bearer \${data.accessToken}\`;

      return api(originalRequest);
    }

    return Promise.reject(error);
  }
);
✅ Store JWT in localStorage or httpOnly cookies for security
💡 Prevent multiple refresh calls with a shared promise
🔍 Use _retry flag to prevent infinite loops on failed refresh
⚡ Automatically retry failed requests after token refresh
authjwttokenrefreshsecurity