Client - cancel duplicate api calls
This commit is contained in:
parent
6982f5320a
commit
a040b0c845
@ -1,5 +1,6 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import { pendingRequests, removeRequestIfPending } from '@/api/pending'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { AUTH_USER_STORE } from '@/store/constants'
|
import { AUTH_USER_STORE } from '@/store/constants'
|
||||||
import { getApiUrl } from '@/utils'
|
import { getApiUrl } from '@/utils'
|
||||||
@ -10,6 +11,11 @@ const authApi = axios.create({
|
|||||||
|
|
||||||
authApi.interceptors.request.use(
|
authApi.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
|
const controller = new AbortController()
|
||||||
|
config.signal = controller.signal
|
||||||
|
const requestKey = removeRequestIfPending(config)
|
||||||
|
pendingRequests.set(requestKey, controller)
|
||||||
|
|
||||||
const authToken = store.getters[AUTH_USER_STORE.GETTERS.AUTH_TOKEN]
|
const authToken = store.getters[AUTH_USER_STORE.GETTERS.AUTH_TOKEN]
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
const auth = `Bearer ${authToken}`
|
const auth = `Bearer ${authToken}`
|
||||||
@ -22,4 +28,17 @@ authApi.interceptors.request.use(
|
|||||||
(error) => Promise.reject(error)
|
(error) => Promise.reject(error)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
authApi.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
removeRequestIfPending(response.config)
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (error.message !== 'canceled') {
|
||||||
|
removeRequestIfPending(error.response.config)
|
||||||
|
}
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export default authApi
|
export default authApi
|
||||||
|
@ -1,9 +1,34 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import { pendingRequests, removeRequestIfPending } from '@/api/pending'
|
||||||
import { getApiUrl } from '@/utils'
|
import { getApiUrl } from '@/utils'
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: getApiUrl(),
|
baseURL: getApiUrl(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
api.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
const controller = new AbortController()
|
||||||
|
config.signal = controller.signal
|
||||||
|
const requestKey = removeRequestIfPending(config)
|
||||||
|
pendingRequests.set(requestKey, controller)
|
||||||
|
return config
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(error)
|
||||||
|
)
|
||||||
|
|
||||||
|
api.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
removeRequestIfPending(response.config)
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (error.message !== 'canceled') {
|
||||||
|
removeRequestIfPending(error.response.config)
|
||||||
|
}
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
export default api
|
export default api
|
||||||
|
18
fittrackee_client/src/api/pending.ts
Normal file
18
fittrackee_client/src/api/pending.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { AxiosRequestConfig } from 'axios'
|
||||||
|
|
||||||
|
export const pendingRequests = new Map()
|
||||||
|
|
||||||
|
const generateRequestKey = (config: AxiosRequestConfig): string => {
|
||||||
|
const { method, url, params = {}, data = {} } = config
|
||||||
|
return [method, url, JSON.stringify(params), JSON.stringify(data)].join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removeRequestIfPending = (config: AxiosRequestConfig): string => {
|
||||||
|
const requestKey = generateRequestKey(config)
|
||||||
|
if (pendingRequests.has(requestKey)) {
|
||||||
|
const controller = pendingRequests.get(requestKey) || {}
|
||||||
|
controller?.abort()
|
||||||
|
pendingRequests.delete(requestKey)
|
||||||
|
}
|
||||||
|
return requestKey
|
||||||
|
}
|
@ -142,8 +142,10 @@ export const actions: ActionTree<IAuthUserState, IRootState> &
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
handleError(context, error)
|
if (error.message !== 'canceled') {
|
||||||
removeAuthUserData(context)
|
handleError(context, error)
|
||||||
|
removeAuthUserData(context)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
[AUTH_USER_STORE.ACTIONS.LOGIN_OR_REGISTER](
|
[AUTH_USER_STORE.ACTIONS.LOGIN_OR_REGISTER](
|
||||||
|
@ -28,7 +28,12 @@ export const handleError = (
|
|||||||
error: AxiosError | null,
|
error: AxiosError | null,
|
||||||
msg = 'UNKNOWN'
|
msg = 'UNKNOWN'
|
||||||
): void => {
|
): void => {
|
||||||
// if stored token is blacklisted
|
// if request is cancelled, no error to display
|
||||||
|
if (error && error.message === 'canceled') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if stored token is blacklisted, disconnect user
|
||||||
if (
|
if (
|
||||||
error?.response?.status === 401 &&
|
error?.response?.status === 401 &&
|
||||||
error.response.data.error === 'invalid_token'
|
error.response.data.error === 'invalid_token'
|
||||||
@ -37,6 +42,7 @@ export const handleError = (
|
|||||||
context.dispatch(AUTH_USER_STORE.ACTIONS.CHECK_AUTH_USER)
|
context.dispatch(AUTH_USER_STORE.ACTIONS.CHECK_AUTH_USER)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const errorMessages = !error
|
const errorMessages = !error
|
||||||
? msg
|
? msg
|
||||||
: error.response
|
: error.response
|
||||||
|
Loading…
Reference in New Issue
Block a user