64 lines
1.4 KiB
TypeScript
64 lines
1.4 KiB
TypeScript
import type { FormError } from '@nuxt/ui/dist/runtime/types'
|
|
|
|
export interface UseSubmitOptions {
|
|
onSuccess?: (result: any) => any
|
|
onError?: (error: Error) => any
|
|
}
|
|
|
|
export function useSubmit<T>(
|
|
fetchable: () => Promise<T>,
|
|
options: UseSubmitOptions = {},
|
|
) {
|
|
const validationErrors = ref<FormError[]>([])
|
|
const error = ref<Error | null>(null)
|
|
const inProgress = ref(false)
|
|
const succeeded = ref<boolean | null>(null)
|
|
|
|
async function submit() {
|
|
validationErrors.value = []
|
|
error.value = null
|
|
inProgress.value = true
|
|
succeeded.value = null
|
|
|
|
try {
|
|
const data = await fetchable()
|
|
succeeded.value = true
|
|
options?.onSuccess?.(data)
|
|
return data
|
|
}
|
|
catch (e: any) {
|
|
error.value = e
|
|
succeeded.value = false
|
|
options?.onError?.(e)
|
|
if (e.data?.errors) {
|
|
const errorsArray: FormError[] = []
|
|
for (const path in e.data.errors) {
|
|
const messages = e.data.errors[path]
|
|
messages.forEach((message: string) => {
|
|
errorsArray.push({ path, message })
|
|
})
|
|
}
|
|
validationErrors.value = errorsArray
|
|
}
|
|
else {
|
|
validationErrors.value = []
|
|
}
|
|
|
|
if (e.response?.status !== 422) {
|
|
throw e
|
|
}
|
|
}
|
|
finally {
|
|
inProgress.value = false
|
|
}
|
|
}
|
|
|
|
return {
|
|
submit,
|
|
inProgress,
|
|
succeeded,
|
|
validationErrors,
|
|
error,
|
|
}
|
|
}
|