axios ignores baseURL in react

Viewed 3089

in my app.js

useEffect(() => {
    axios.defaults.headers.common["token"] =
      process.env.REACT_APP_SITE_TOKEN;
    axios.defaults.baseURL = "https://api.example.com";
  }, []);

in my redux action file:

export const getCollectionByToken = (token) => async (dispatch) => {
  console.log(axios.defaults); //logs https://api.exapmle.com
  try {
    const res = await axios.get("/collections/" + token);
    console.log(res);
    dispatch({ type: SET_CURRENT_COLLECTION, payload: res.data });
...

but somehow, the requests are going to http://localhost:3000/collection/<token>

2 Answers

UseEffect is run after the a component is mounted and your redux action is probably compiled before that. The browser console.log is sometimes buggy which print with the wrong sequence.

try:

export const getCollectionByToken = (token) => async (dispatch) => {
  axios.defaults.headers.common["token"] =
      process.env.REACT_APP_SITE_TOKEN;
    axios.defaults.baseURL = "https://api.example.com";
  try {
    const res = await axios.get("/collections/" + token);
    console.log(res);
    dispatch({ type: SET_CURRENT_COLLECTION, payload: res.data });
    ...

or according to the document, create an instance somewhere, say a file axiosConfig.ts

import axios from 'axios'

// Set config defaults when creating the instance
const axiosInstance = axios.create({
  baseURL: 'https://api.example.com'
});

// Alter defaults after instance has been created
axiosInstance.defaults.headers.common['token'] = process.env.REACT_APP_SITE_TOKEN;

export default axiosInstance;

Then when you want to use axios, import the instance instead of the axios from the library directly:

import axiosInstance from './axiosConfig';

export const getCollectionByToken = (token) => async (dispatch) => {
  try {
    const res = await axiosInstance.get("/collections/" + token);
    dispatch({ type: SET_CURRENT_COLLECTION, payload: res.data });
    ...

you can add interceptors, also there is a es6 class wrapper for axios.

$ npm install @eneto/axios-es6-class

you need to create your own api class that will extends from Api.

assume we are creating a class UsersApi

import { Api } from '@eneto/axios-es6-class';

// process.env.API_BASE_URL = localhost:3001

export class UserApi extends Api {
    public constructor (config) {
        super(config);

        // this middleware is been called right before the http request is made.
        this.interceptors.request.use(param => {
            const {API_BASE_URL} = process.env;
          return {
              ...param,
              baseUrl: API_BASE_URL,
              defaults: {
                  headers: {...param.defaults.headers}
              }
          }
        });

        // this middleware is been called right before the response is get it by the method that triggers the request
        this.interceptors.response.use(param => {
          return {  ...param}
        });

        this.userLogin = this.userLogin.bind(this);
        this.userRegister = this.userRegister.bind(this);
    }

    public userLogin (credentials) {
        return this.post("/login", credentials)
            .then(this.success);
    }

    public userRegister (user) {
        return this.post("/register", user)
            .then(this.success)
            .catch((error) => {
                throw error;
            });
    }


}

Related