Would be glad to get an idea of how to destruct my code for avoiding a require cycle (I'm not encountering any bug or so, just want to make my code the best possible, w/t memory leaking, encounter unset vars or damage performance/readability)
My hierarchy looks like so:
services
-- api.ts
-- userService.ts
store
-- actions
---- auth.ts
-- index.tsx
-- jwt.ts
At store/index.tsx I'm importing store/jwt.ts for -
const store = createStore(reducer, compose(applyMiddleware(thunk, jwt)))
While at store/jwt.ts I'm importing actions/auth.ts for -
import { refreshToken as refreshTokenFunc } from './actions/auth'
const jwt: Middleware = ({ dispatch, getState }: { dispatch; getState: () => IRootState }) => {
return (next) => (action) => {
const nextAction = () => next(action)
if (should refresh token) {
return !getState().auth.refreshTokenPromise
? refreshTokenFunc(dispatch).then(nextAction)
: getState().auth.refreshTokenPromise.then(nextAction)
}
return nextAction()
}
}
(While I'm having refreshTokenPromise as a redux variable for avoiding calling refresh token endpoint a few times in a row but waiting for the same call to end.)
refreshTokenFunc from actions/auth.ts uses userService.refreshToken (and imports userService...)
export async function refreshToken(dispatch) {
const handleErr = () => Promise.reject(dispatch(logout()))
const refreshTokenPromise = userService
.refreshToken(... some params)
.then(({ status, ...rest }) => {
status
? dispatch(...)
: handleErr()
})
.catch(handleErr)
await dispatch({
type: AUTH_REFRESH_TOKEN,
refreshTokenPromise
})
return refreshTokenPromise
}
services/userService.ts imports main services/api.ts service
import API from './api'
refreshToken: (params) =>
API.post(EEndPoints.REFRESH_TOKEN, ...params)
and services/api.ts imports store/index.tsx for common getState either dispatch common things as
store.dispatch({ type: GENERAL_TOGGLE_NO_INTERNET })
store.dispatch({ type: AUTH_LOGOUT }) // in case token sent returned as invalid by API...)
to sum up -
services/userService.ts -> services/api.ts -> store/index.tsx -> store/jwt.ts -> store/actions/auth.ts -> services/userService.ts
I'm sure I'm not the first one using middleware for refreshing tokens, having this kind of hierarchy, or using a main api service with common dispatch or getState, so maybe someone found a way around this loop. Any time I try to change some of the imports I still have this loop just from a different file to a different file (for example from store/actions/auth.ts to itself back)
I tried to keep the code as minimal as possible, in case it's not clear enough please comment.
Any idea/thought will be very appreciated! :)