Axios does not cancel my HTTP request in ReactJS

Viewed 100

I hope you are fine, I have a problem canceling my axios request with the useEffect hook in ReactJS.

Explanation

First of all, you should know that my code uses a file called Requests.js, there my custom requests are stored, such as: signup, start session and consult user information.

In these functions I receive the url, the data to send and some headers.

When I use these functions in my main code I pass a cancellation token created by axios, this token is created when the form is submitted, and if the user leaves the page in that timeframe, I cancel the axios request.

Where you may have the problem is how I pass the cancellation token to axios, since I pass it in function in function, until I get to the function of axios.

Request.js

import { LOGIN_URL, SIGNUP_URL, GET_INFO_USER_LOGGED } from "../Config/api";
import { alertDanger } from "./notifications";

class Requests {
  _showNetworkErrorAlert(status) {
    if (status >= 400 && status < 500) {
      alertDanger("A client network error occurred.");
    } else if (status >= 500 && status < 600) {
      alertDanger("Platform server error.");
    } else {
      alertDanger("A connection error occurred.");
    }
  }

  async _post(url, args, headers) {
    console.log({ ...headers });
    try {
      const res = await axios.post(
        url,
        {
          ...args,
        },
        {
          ...headers, // here I receive the headers (including the cancellation token)
        }
      );
      return res;
    } catch (error) {
      this._showNetworkErrorAlert(error?.response?.status);
    }
  }

  async _get(url, args, headers) {
    console.log(headers);
    try {
      const res = await axios.get(url, {
        ...args,
        headers,
      });
      return res;
    } catch (error) {
      this._showNetworkErrorAlert(error.response.status);
    }
  }

  async login({ email, password, headers }) {
    
    // here I pass the parameters with the headers (and the cancellation token)
    const loginUser = await this._post(LOGIN_URL, { email, password }, headers);
    return loginUser;
  }

  async signup({ username, email, password, headers }) {
    const signupUser = await this._post(
      SIGNUP_URL,
      {
        username,
        email,
        password,
      },
      headers // Here same as the previous ones
    );
    return signupUser;
  }

  async getInfoUserLogged(token) {
    const userInfoLogged = await this._get(
      GET_INFO_USER_LOGGED,
      {},
      {
        authorization: `Bearer ${token}`,
      }
    );
    return userInfoLogged?.data?.data?.user;
  }
}

export default new Requests();

My file generating the problem.

import { Redirect } from "react-router-dom";
import axios from "axios";

// import { useSelector } from 'react-redux';

// components
import LoginComponent from "./LoginComponent";
import { alertDanger, alertSuccess } from "../../../Helpers/notifications";

// Redux elements
import { connect } from "react-redux";
import { SetCurrentUserInfo } from "../../../Redux/Actions/UserActions";

// api links
import Resquests from "../../../Helpers/Resquests";

const LoginContainer = (props) => {
  const [credentials, setCredentials] = useState({
    email: "",
    password: "",
  });

  const [isLogged, setLogged] = useState(false);
  const [isLoading, setLoading] = useState(false);
  let cancelResquest = null;

  /*
  
    This cancellation of the petition DOES NOT WORK
  */
  useEffect(() => {
    return () =>
      cancelResquest && cancelResquest.cancel("Finalizando peticion");
  }, []);

  const onChangeCredentials = ({ target }) => {
    setCredentials({
      ...credentials,
      [target.name]: target.value,
    });
  };

  const onSubmitForm = async (ev) => {
    ev.preventDefault();
    setLoading(true);

    /*
      Here I generate my token when the form is submitted
    */
    cancelResquest = axios.CancelToken.source();
    const res = await Resquests.login(
      {  
        email: credentials.email,
        password: credentials.password,

      }, // The third parameter is the "headers"
      {
        cancelToken: cancelResquest.token, // the token
      }
    );

    setLoading(false);

    if (res?.data?.ok === false) {
      alertDanger("Error in your credentials");
    } else if (res?.data?.ok === true) {
      alertSuccess("Successful login.");
      const userInfoLogged = await Resquests.getInfoUserLogged(
        res.data.data.token
      );

      props.SetCurrentUserInfo(userInfoLogged);
      console.log("en la linea 49", props.UserInformation);

      setLogged(true);
    }
  };

  console.log("en la linea 53", props.UserInformation);

  return isLogged ? (
    <Redirect to="/" />
  ) : (
    <LoginComponent
      {...{ onChangeCredentials, ...credentials, onSubmitForm, isLoading }}
    />
  );
};

const mapStateToProps = (state) => ({
  UserInformation: state.UserInformation,
});

const mapDispatchToProps = {
  SetCurrentUserInfo,
};

export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer);

Thank you very much in advance for reading this.

0 Answers
Related