What is the correct way to implement Axios interceptor in TypeScript?

I have implemented an axios interceptor:

instance.interceptors.response.use(async (response) => {
    return response.data;
  }, (err) => {
    return Promise.reject(err);
  });

This interceptor retrieves the data property from the response.

The response object is of type AxiosResponse<any, any>, and the data property contains data of type

AxiosResponse<any, any>.data
.

The issue arises when I utilize this axios client:

const instance = axios.create({...});
// ...etc
// add interceptor

then I do:

customAxiosClient.get().then((data: /* here data is of type AxiosResponse instead of AxiosResponse.data */)

How can I resolve this problem?

Answer №1

All you need to do is indicate the specific data type of the response in the axios get method, as shown below:

axios.get<never, YourDataType>(...)

Answer №2

Rechu's solution works fine, but I have an alternative approach.

To maintain a global axios instance, you can create a reusable function. This is a method I personally use in live projects.

To begin, create a folder/file named utils/http.ts within your project. Here is the custom function that consolidates everything:

import axiosClient from "axios";
import type { AxiosRequestConfig } from "axios";

/**
 * Initializes an 'axios' instance with customized settings.
 */
const instance = axiosClient.create({
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json; charset=utf-8",
  },
});

/**
 * Handles all responses. It's possible to include request handlers as well,
 * omitted here for simplicity.
 */
instance.interceptors.response.use(
  (res) => res.data,
  (err) => {
    if (err.response) {
      return Promise.reject(err.response.data);
    }

    if (err.request) {
      return Promise.reject(err.request);
    }

    return Promise.reject(err.message);
  }
);

/**
 * Replaces main `axios` instance with the customized one.
 *
 * @param cfg - Configuration object for Axios.
 * @returns A promise containing the response of the HTTP request with the 'data' object already
 * deconstructed.
 */
const axios = <T>(cfg: AxiosRequestConfig) => instance.request<any, T>(cfg);

export default axios;

Finally, implement it as shown in the code snippet below:

const login = () => {
  const creds = { username: "user", password: "pass" };

  axios<User>({ method: "POST", url: "/api/v1/auth/login", data: creds })
    .then((user) => { /* process user data */ })
    .catch((err) => { /* handle errors */ );
};

This setup will be properly typed and immediately usable. You can replace any with unknown within the axios function as needed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring secure routes in Node.js with test cases using Mocha and Chai?

The function verifies whether the route is accessible or not function checkSessionCookieValidity(req, res, next) { if (!isValid(req.session)) { return res.status(401).json({ isLoggedIn: false }); } return next ...

Creating a React Typescript interface with nested interfaces for props

My issue is with a functional component that is supposed to receive props from another functional component. The problem lies in the fact that an interface within the receiving component always returns 'undefined' when I log it in the console. De ...

Update the CSS styles using properties specified within an object

Is it possible to dynamically apply CSS styles stored in a JavaScript object to elements? For instance, can we change the width and background of a basic <div> element: <div id="box"></div> <button id="btn">click me</button> ...

Developing an identical design and layout but utilizing a distinct domain name for the company

After being given the task of creating a website identical to an existing one with a different domain name on WordPress, I proposed using the parent HTML source code or cloning it to speed up the project. The client agreed, explaining that starting from sc ...

Toggle the Visibility of your Password

I am currently working on implementing a TypeScript function in my webpage to enable the toggling of password visibility using an icon. The desired functionality is as follows: when a button (in this case, a clickable icon) is pressed, the icon should chan ...

Prevent zooming or controlling the lens in UIWebview while still allowing user selection

Is there a way to disable the zoom/lens on uiwebview without affecting user selection? I'm trying to avoid using "-webkit-user-select:none" in my css. -webkit-user-select:none ...

How can I create a Discord bot command that ignores case sensitivity?

I wrote a custom "roleinfo" command for my Discord bot, but I'm struggling to make the role search case insensitive. Here is the code snippet: const Discord = require("discord.js"); module.exports.run = async (bot, message, args) => { //Me ...

Issue with Google Charts where the label does not show outside of the bar if the bar is too small

I am encountering an issue with my Google Bar Chart where the bar label is not displaying outside of the bar when it is too large to fit inside. This behavior should be the default, but my charts are not working as expected. The problem can be seen in rows ...

Achieving dynamic page number display in relation to Pagination in ReactJS

I have a website that was created by someone else, and the pagination feature is becoming overwhelming for me as I am not a coder or developer. Image Link Currently, my navigation pagination displays 17 pages. I would like to limit this to only showing 1 ...

Introducing HTML elements into pre-existing web pages

My interest lies in the idea of injecting HTML into existing web pages for enhanced functionality. Specifically, I am exploring the concept of creating a more efficient bookmarking system. As someone new to web development, I am unsure of how to achieve th ...

Web performance issues noticed with Angular 8 and Webpack 3.7 rendering speed

My web application is currently taking 35 seconds to render or at least 1.15 seconds from the initial Webpack start. I've made efforts to optimize Webpack, which has improved the launch speed, but the majority of time is consumed after loading main.j ...

What is the best way to mark a specific photo as a favorite in an array of Photo objects?

I am working with a basic array of photo categories that follows this structure: [ { category: 1001, photos: [ { id: 100101, url: 'url.com/100101', favorite: false}, { id: 100102, url: 'url.com/100102', favorite: ...

finding the initial element within an object using lodash in javascript

Recently, I came across some data in the form of an array of objects. For instance, let me share a sample dataset with you: "data": [ { "name": "name", "mockupImages": "http://test.com/image1.png,http://test.com/image2.png" }] ========================== ...

Double up on your calls to the subscribe function in Angular to ensure successful login

Within my angular 7 application, there is a sign in component that triggers the sign in function within the authentication service. This function initiates an HTTP post request and then subscribes to the response. My goal is to have both the auth service f ...

Trigger the datepicker's onselect event programmatically

Does anyone know how to manually trigger the onselect event of a datepicker? My code is currently functioning correctly (retrieving data from a database based on the value of the datepicker's altfield), but I'm having an issue where the onselect ...

Issue: ENOENT - The specified file or directory, './views/s.ejs', does not exist in Node.js Express

Encountering an error when attempting to render a file from the 'views' directory in the 'routes'. The specific error message is as follows: Error: Valid Login { [Error: ENOENT: no such file or directory, open './views/s ...

I am currently experiencing difficulties with uploading an image from the admin panel in Magento 1.9. Instead of receiving the expected response, I am

I encountered an error while trying to upload a file in Magento for a product image. When I click on upload, an error is displayed during the file upload process. Upon further investigation in the product.js file for item response, I noticed that HTML is b ...

Redux - Preventing Overwriting of Product Quantity in Cart by Creating a New Object

Is there a way to address the issue where adding the same product multiple times to the cart creates new objects instead of increasing the quantity? switch (action.type) { case actionTypes.ADD_TO_CART: const product = state.products.find((p) = ...

Can AJAX be considered a backend tool for retrieving data from servers?

I'm curious to find out if ajax is primarily used as a backend technology for retrieving data or if it's mainly considered a frontend tool. My attempts to research this on Google have not yielded a definitive answer. ...

Create a circle surrounding the latitude and longitude on a Bing Maps angular display

I successfully integrated the Bing map with Angular using the angular-map package, and now I want to draw a circle around a given latitude and longitude. To achieve this, I installed the following npm packages: npm install --save angular-maps npm ins ...