Axios returning undefined is not an object (evaluating 'config.cancelToken')

Viewed 130

I have a react native application. I am making an authenticated API call to my serve using a GET request.

I am confident that this error is on the client side as I can see the request processed and returned on the server-side while I watch the EC2 instance execute the response. Token is valid, endpoint is valid, information is returned.

What I do see is an error

  const response = axiosContext.authAxios
    .get("/dashboard")
    .then((res) => {
      console.log(res);
    })
    .catch((error) => {
      console.log(error); // here  undefined is not an object (evaluating 'config.cancelToken')
    });

I do not call the cancel request I am aware there is one in Axios; why this is showing I am unsure.

AxiosContext.js

import React, { createContext, useContext } from "react";
import axios from "axios";
import { AuthContext } from "./AuthContext";
import createAuthRefreshInterceptor from "axios-auth-refresh";
import * as Keychain from "react-native-keychain";
import { getSecretValueFor, isSessionTokenExpired } from "../helpers/common";

const AxiosContext = createContext();
const { Provider } = AxiosContext;


const AxiosProvider = ({ children }) => {
  const authContext = useContext(AuthContext);

  const authAxios = axios.create({
    baseURL: "http://someAPiIcom:443",
    timeout: 9000,
  });

  const publicAxios = axios.create({
    baseURL: "http://someAPI.com:443",
    timeout: 9000,
  });
  

  authAxios.interceptors.request.use(
    (config) => {
      if (!config.headers.Authorization) {
        return getSecretValueFor("session_token")
          .then((session_token) => {
            config.headers.Authorization = session_token; // gets the jwt I store ( works and accepted by server
            return config
          })
          .catch((error) => {
            console.log(error);
          });
      }
      return config;
    },

    (error) => {
      return Promise.reject(error);
    }
  );

  const refreshAuthLogic = (failedRequest) => {
    const data = {
      refreshToken: authContext.authState.refreshToken,
    };

    const options = {
      method: "POST",
      data,
      url: "http://localhost:3000/api/refreshToken",
    };

    return axios(options)
      .then(async (tokenRefreshResponse) => {
        failedRequest.response.config.headers.Authorization =
          "Bearer " + tokenRefreshResponse.data.accessToken;

        authContext.setAuthState({
          ...authContext.authState,
          accessToken: tokenRefreshResponse.data.accessToken,
        });

        await Keychain.setGenericPassword(
          "token",
          JSON.stringify({
            accessToken: tokenRefreshResponse.data.accessToken,
            refreshToken: authContext.authState.refreshToken,
          })
        );

        return Promise.resolve();
      })
      .catch((e) => {
        authContext.setAuthState({
          accessToken: null,
          refreshToken: null,
        });
      });
  };

  createAuthRefreshInterceptor(authAxios, refreshAuthLogic, {});

  return (
    <Provider
      value={{
        authAxios,
        publicAxios,
      }}
    >
      {children}
    </Provider>
  );
};

export { AxiosContext, AxiosProvider };

AuthContext.js

import React, { createContext, useState } from "react";
import * as Keychain from "react-native-keychain";
import {
  saveSecretValue,
  getUTCTimestamp,
  getSecretValueFor,
} from "../helpers/common";

const AuthContext = createContext(null);
const { Provider } = AuthContext;

const AuthProvider = ({ children }) => {
  const [authState, setAuthState] = useState({
    accessToken: null,
    refreshToken: null,
    authenticated: null,
  });

  const logout = async () => {
    await Keychain.resetGenericPassword();
    setAuthState({
      accessToken: null,
      refreshToken: null,
      authenticated: false,
    });
  };

  const getAccessToken = () => {
    getSecretValueFor("session_token")
      .then((session_token) => {
        return session_token;
      })
      .catch((error) => {
        return error;
      });
  };

  return (
    <Provider
      value={{
        authState,
        getAccessToken,
        setAuthState,
        logout,
      }}
    >
      {children}
    </Provider>
  );
};

export { AuthContext, AuthProvider };

Main.js

import { AuthContext } from "./context/AuthContext";
import { AxiosContext } from "./context/AxiosContext";

const Stack = createStackNavigator();

export default function Main(props) {
  const [status, setStatus] = useState("loading");
  const authContext = useContext(AuthContext);
  const axiosContext = useContext(AxiosContext);
  const loadJWT = useCallback(async () => {
    try {
      const response = axiosContext.authAxios
        .get("/dashboard")
        .then((res) => {
          console.log(res);
        })
        .catch((error) => {
          console.log(error); // error thrown here
        });
      console.log(response);

      const jwt = await getSecretValueFor("session_token");
      authContext.setAuthState({
        accessToken: jwt.accessToken || null,
        refreshToken: jwt.refreshToken || null,
        authenticated: jwt.accessToken !== null,
      });

      const isTokenExpired = isSessionTokenExpired(jwt);
      if (isTokenExpired) {
        console.log("Token expired");
        await setStatus("error");
      } else {
        console.log("Token valid");
        await setStatus("success");
      }
    } catch (error) {
      console.log(error);

      await setStatus("error");
      // useEffect(() => { setStatus("success") })
      console.log(`Keychain Error: ${error.message}`);
      authContext.setAuthState({
        accessToken: null,
        refreshToken: null,
        authenticated: false,
      });
    }
  }, []);
0 Answers
Related