node.jsreactjsurlaxiosapprequests

React: API url works in GET request but it gets changed in POST request


I am trying to set the api urls for my react app. The GET endpoints work perfectly but when I make a post request the URL becomes the localhost URL without any reason.

I am using a Constants.js file where I check if the node environment is in development or production. This is how they look in production.

const dev = {
  url: "http://127.0.0.1:8000/",
};

const prod = {
  url: "https://myapp.herokuapp.com/",
};

console.log(process.env.NODE_ENV);

export const config = process.env.NODE_ENV === "development" ? dev : prod;

Currently I have them inverted so that I can make requests to the server on heroku.

const prod = {
  url: "http://127.0.0.1:8000/",
};

const dev = {
  url: "https://myapp.herokuapp.com/",
};

console.log(process.env.NODE_ENV);

export const config = process.env.NODE_ENV === "development" ? dev : prod;

Here I am importing the config and making a GET request with the variable works perfectly fine.

export const loadUser = () => (dispatch, getState) => {
  dispatch({ type: USER_LOADING });

  axios
    .get(`${config.url}accounts/api/auth/user`, tokenConfig(getState))
    .then((res) => {
      dispatch({
        type: USER_LOADED,
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch(returnErrors(err.response.data, err.response.status));
      dispatch({
        type: AUTH_ERROR,
      });
    });
};

Here is where it gets weird. When I make the POST request the URL gets changed to the localhost.

export const login = (username, password) => (dispatch) => {
  const config = {
    headers: {
      "Content-Type": "application/json",
    },
  };

  const body = JSON.stringify({
    username,
    password,
  });

  axios
    .post(`${config.url}accounts/api/auth/login`, body, config)
    .then((res) => {
      dispatch({
        type: LOGIN_SUCCESS,
        payload: res.data,
      });
    })
    .catch((err) => {
      dispatch(returnErrors(err.response.data, err.response.status));
      dispatch({
        type: LOGIN_FAILED,
      });
    });
};

This is the error I get in the console

VM159:1 POST http://localhost:3000/undefinedaccounts/api/auth/login 404 (Not Found)

As you can see the URL gets changed to the localhost and an undefined is passed to the URL which I do not know from where it comes.

If someone has any idea of what is happening here I would really appreciate some help, thanks.


Solution

  • The easiest way to fix this would be by setting baseURL:

    Either as a default config:

    axios.defaults.baseURL = 'https://api.example.com';
    

    Or, as the baseURL of your axios custom instance:

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

    Issue in your code:

    When you wrote:

    axios.post(`${config.url}accounts/api/auth/login`, body, config)...
    

    where config is:

    const config = {
        headers: {
          "Content-Type": "application/json",
        },
      };
    

    and it has "headers" only, hence "url" is simply undefined. To fix it, you should add "url" property as well in config object.