How to create promise instance with axios create

I’m new to TypeScript so I learn as I go along. I want to create an axios instace to reuse in my code where I only need to pass props where needed. Im using React.

// in a utils folder
// axios.ts

import axios from 'axios'

type Method =
    | 'get' | 'GET'
    | 'delete' | 'DELETE'
    | 'head' | 'HEAD'
    | 'options' | 'OPTIONS'
    | 'post' | 'POST'
    | 'put' | 'PUT'
    | 'patch' | 'PATCH'
    | 'link' | 'LINK'
    | 'unlink' | 'UNLINK'

interface AxiosProps {
    /** Web URL */
    url: string,
    /** 
     * POST method: GET, POST, PUT, DELETE 
     * @default GET
     */
    method?: Method,
    /** Header options */
    header?: object,
    /** Optional Data for POST */
    data?: object,
    /** Optional params */
    params?: object
}

export function Axios(props: AxiosProps) {

    /**
     * Creates an axios instance.
     * 
     * @see https://github.com/axios/axios
     * @return Promise
     */
    const instance =  axios.create({
        baseURL: process.env.REACT_APP_API_ENDPOINT,
        headers: { 'Content-Type': 'application/json' },
        url: props.url, // must have a starting backslash: /foo
        params: props.params,
        data: props.data,
        withCredentials: true,
    })

    return instance
}

I got the Method type from axios.

Now, using the instance:

import {Axios} from '../utilities/axios'

// I'd like to achieve this in an async function:
const {data} = await Axios({url: '/foo' /**, method: 'POST' **/})
console.log(data)

The above, TS complains about:

‘await’ has no effect on the type of this expression

How to achieve this logic, please? I know I need to learn more typescript but I’d a take a “beaten” while I learn. Thanks

3 Answers

The reason why you’re getting that error is because your Axios is an axios instance. I assume you want to use the request function of your axios instance which has the following type signature:

request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>;

Also, you cant use an asynchronous action in the ‘global’ context of your file. You should define an async function as following:

async function fetchData(): Promise<void> {
  const { data } = await Axios.request({ url: '/foo', method: 'GET' });
  ...
}

fetchData();

Some coding style tips: Best practice is to only use uppercases for classes. In your case you could do something such as

export const axiosInstance = axios.create({
  baseURL: process.env.REACT_APP_API_ENDPOINT,
  headers: { 'Content-Type': 'application/json' },
  url: props.url, // must have a starting backslash: 
  params: props.params,
  data: props.data,
  withCredentials: true,
});

function Axios(...) isn’t a async function, so there is no need to use await, because it doesn’t return a promise and that is why you get 'await' has no effect on the type of this expression.

I think you need to use interceptors

export function Axios(props: AxiosProps) {

    /**
     * Creates an axios instance.
     * 
     * @see https://github.com/axios/axios
     * @return Promise
     */
    const instance =  axios.create({
        baseURL: process.env.REACT_APP_API_ENDPOINT,
        headers: { 'Content-Type': 'application/json' },
        url: props.url, // must have a starting backslash: /foo
        params: props.params,
        data: props.data,
        withCredentials: true,
    })

    instance.interceptors.response.use(
      response => response,
      error => error,
    );

    return instance
}

Archive from: https://stackoverflow.com/questions/59070235/how-to-create-promise-instance-with-axios-create

Leave a Reply

Your email address will not be published. Required fields are marked *