I am trying to build a react app using relay following instructions from the react-relay step by step guide. In the guide the auth token is stored in the env file, and I am trying to retrieve my token from memory which is created when the user logs in and is passed down to all components using the context API. I am not storing it in local storage and have a refresh token to automatically refresh the JWT.
From the tutorial, the relay environment class is not a React component because of which I cannot access the context object.
Is there a way to pass the token from my context to the relay environment class or any middleware implementation to accomplish this.
Any help is greatly appreciated.
import { useContext } from 'react';
import { Environment, Network, RecordSource, Store } from 'relay-runtime';
import axios from "axios";
import { AppConstants } from './app-constants';
import { AuthContext, AuthSteps } from "./context/auth-context";
import { useCookie } from './hooks/useCookie';
interface IGraphQLResponse {
data: any;
errors: any;
}
async function fetchRelay(params: { text: any; name: any; }, variables: any, _cacheConfig: any) {
const authContext = useContext(AuthContext); //Error - cannot access context
const { getCookie } = useCookie(); //Error - cannot access context
axios.interceptors.request.use(
(config) => {
const accessToken = authContext && authContext.state && authContext.state.token;
if(accessToken) config.headers.Authorization = `Bearer ${accessToken}`;
return config;
},
(error) => {
Promise.reject(error);
}
);
axios.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const originalRequest = error.config;
const refreshToken = getCookie(AppConstants.AUTH_COOKIE_NAME);
if(refreshToken && error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const response = await axios
.post(process.env.REACT_APP_REFRESH_TOKEN_API_URL!, { refreshToken: refreshToken });
if (response.status === 200 && response.data && response.data.accessToken) {
authContext && authContext.dispatch && authContext.dispatch({
payload: {
token: response.data.accessToken
},
type: AuthSteps.SIGN_IN
});
accessToken = response.data.accessToken;
return axios(originalRequest);
}
}
return Promise.reject(error);
}
);
const data: IGraphQLResponse = await axios.post(process.env.REACT_APP_GRAPHQL_URL!, {
query: params.text,
variables
});
if(Array.isArray(data.errors)) {
throw new Error(
`Error fetching GraphQL query '${
params.name
}' with variables '${JSON.stringify(variables)}': ${JSON.stringify(
data.errors,
)}`,
);
}
return data;
}
export default new Environment({
network: Network.create(fetchRelay),
store: new Store(new RecordSource(), {
gcReleaseBufferSize: 10,
}),
});