Skip to content

Commit

Permalink
feat(useAxios): added initialData and resetOnExecute options (#2791)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
Alfred-Skyblue and antfu committed Apr 13, 2023
1 parent 3996d44 commit f54a3c4
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 5 deletions.
47 changes: 47 additions & 0 deletions packages/integrations/useAxios/index.test.ts
Expand Up @@ -301,6 +301,53 @@ describe('useAxios', () => {
expect(isLoading.value).toBeFalsy()
})

test('should use initialData', async () => {
const { data } = useAxios(url, config, { ...options, initialData: { value: 1 } })
expect(data.value).toEqual({ value: 1 })
})

test('should reset data when execute', async () => {
interface ResType {
id: number
title: string
body: string
userId: number
}
const initialData: ResType = {
id: 2,
title: 'title',
body: 'body',
userId: 2,
}
const { data, execute } = useAxios<ResType>(url, config, { ...options, initialData, resetOnExecute: true })
expect(data.value).toEqual(initialData)
await execute()
expect(data.value).toEqual({ completed: false, id: 1, title: 'delectus aut autem', userId: 1 })
await execute('/todos/312')
expect(data.value).toEqual(initialData)
})

test('should not reset data when execute', async () => {
interface ResType {
id: number
title: string
body: string
userId: number
}
const initialData: ResType = {
id: 2,
title: 'title',
body: 'body',
userId: 2,
}
const { data, execute } = useAxios<ResType>(url, config, { ...options, initialData })
expect(data.value).toEqual(initialData)
await execute()
expect(data.value).toEqual({ completed: false, id: 1, title: 'delectus aut autem', userId: 1 })
await execute('/todos/312')
expect(data.value).toEqual({ completed: false, id: 1, title: 'delectus aut autem', userId: 1 })
})

test('should call onFinish', async () => {
const onFinish = vi.fn()
const { execute, isLoading, isFinished } = useAxios(url, config, { ...options, onFinish })
Expand Down
40 changes: 35 additions & 5 deletions packages/integrations/useAxios/index.ts
@@ -1,6 +1,6 @@
import type { Ref, ShallowRef } from 'vue-demi'
import { ref, shallowRef } from 'vue-demi'
import { isString, until } from '@vueuse/shared'
import { isString, noop, until } from '@vueuse/shared'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, CancelTokenSource } from 'axios'
import axios, { AxiosError } from 'axios'

Expand Down Expand Up @@ -85,6 +85,17 @@ export interface UseAxiosOptions<T = any> {
* Callback when success is caught.
*/
onSuccess?: (data: T) => void

/**
* Initial data to use
*/
initialData?: T

/**
* Sets the state to initialState before executing the promise.
*/
resetOnExecute?: boolean

/**
* Callback when request is finished.
*/
Expand Down Expand Up @@ -138,8 +149,17 @@ export function useAxios<T = any, R = AxiosResponse<T>, D = any>(...args: any[])
)
options = args[args.length - 1]

const {
initialData,
shallow,
onSuccess = noop,
onError = noop,
immediate,
resetOnExecute = false,
} = options

const response = shallowRef<AxiosResponse<T>>()
const data = options.shallow ? shallowRef<T>() : ref<T>()
const data = (shallow ? shallowRef : ref)<T>(initialData!) as Ref<T>
const isFinished = ref(false)
const isLoading = ref(false)
const isAborted = ref(false)
Expand All @@ -162,6 +182,14 @@ export function useAxios<T = any, R = AxiosResponse<T>, D = any>(...args: any[])
isLoading.value = loading
isFinished.value = !loading
}

/**
* Reset data to initialData
*/
const resetData = () => {
if (resetOnExecute)
data.value = initialData!
}
const waitUntilFinished = () =>
new Promise<OverallUseAxiosReturn<T, R, D>>((resolve, reject) => {
until(isFinished).toBe(true)
Expand All @@ -182,26 +210,28 @@ export function useAxios<T = any, R = AxiosResponse<T>, D = any>(...args: any[])
isFinished.value = true
return { then }
}
resetData()
abort()
loading(true)
instance(_url, { ...defaultConfig, ...typeof executeUrl === 'object' ? executeUrl : config, cancelToken: cancelToken.token })
.then((r: any) => {
response.value = r
const result = r.data
data.value = result
options.onSuccess?.(result)
onSuccess(result)
})
.catch((e: any) => {
error.value = e
options.onError?.(e)
onError(e)
})
.finally(() => {
options.onFinish?.()
loading(false)
})
return { then }
}
if (options.immediate && url)

if (immediate && url)
(execute as StrictUseAxiosReturn<T, R, D>['execute'])()

const result = {
Expand Down

0 comments on commit f54a3c4

Please sign in to comment.