Created
February 28, 2023 21:04
-
-
Save 7iomka/3304ff1f59961426cf8a070ada6ce876 to your computer and use it in GitHub Desktop.
Factory example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createLib, ValidationVisibilityCondition } from '@filledout/core'; | |
import { createLib as createReactLib } from '@filledout/react'; | |
import type { ApplyYupParams } from '@filledout/yup'; | |
import { applyYup } from '@filledout/yup'; | |
import type { FormModel, CreateFormParams } from '@filledout/core'; | |
import type { AxiosError } from 'axios'; | |
import { isAxiosError } from 'axios'; | |
import type { EffectParams, Effect } from 'effector'; | |
import { createEffect, is, sample } from 'effector'; | |
import { getErrorsMap, isCustomAxiosError } from '../api'; | |
import { showNotificationFx } from '../lib/notification'; | |
// eslint-disable-next-line @typescript-eslint/no-unused-vars | |
type ApplyCustomParams<V> = unknown; | |
type CreateFormPathedParams<V> = CreateFormParams<V> & ApplyYupParams<V> & ApplyCustomParams<V>; | |
// Core lib | |
const lib = createLib({ | |
showValidationOn: [ | |
ValidationVisibilityCondition.Submitted, | |
ValidationVisibilityCondition.Touched, | |
// ValidationVisibilityCondition.Dirty | |
], | |
}); | |
const createForm = <V>(params: CreateFormPathedParams<V>) => { | |
const $$form = lib.createForm<V>(params); | |
// apply own custom rules | |
handleForm($$form, params); | |
return { | |
...$$form, | |
// apply yup validation rules | |
...applyYup($$form, params), | |
}; | |
}; | |
// Additional rules of form data processing | |
function handleForm<V>($$form: FormModel<V, object>, { onSubmit }: CreateFormPathedParams<V>) { | |
const onSubmitFx = is.effect(onSubmit) | |
? (onSubmit as Effect<V, any, Error>) | |
: createEffect<V, any, Error>(() => {}); | |
// Handle onSubmit response errors as externalErrors | |
// If custom axios error | |
sample({ | |
clock: onSubmitFx.failData, | |
filter: isCustomAxiosError, | |
fn: getErrorsMap, | |
target: $$form.$externalErrors, | |
}); | |
// Handle reset external errors on form values changes / submit attempt | |
sample({ | |
clock: [$$form.$values.updates, $$form.submit], | |
fn: () => ({}), | |
target: $$form.$externalErrors, | |
}); | |
// If response has exception or interner connection error | |
sample({ | |
clock: onSubmitFx.failData, | |
filter: (error) => { | |
return !isCustomAxiosError(error); | |
}, | |
fn: (error) => { | |
let title = 'Ошибка'; | |
let message = 'Ошибка на сервере'; | |
if (isAxiosError(error)) { | |
const errorResponse = (error as AxiosError).response; | |
if (!errorResponse) { | |
message = | |
error.code === 'ERR_NETWORK' | |
? 'Проверьте интернет соединение' | |
: 'Не удалось отправить форму'; | |
} else { | |
title = `Ошибка (${errorResponse.status})`; | |
message = | |
errorResponse.status === 500 ? 'Внутренняя ошибка сервера' : errorResponse.statusText; | |
} | |
} else { | |
// throw new Error(error.message); | |
console.error(error.name, error.message, error.stack); | |
message = `Что-то пошло не так ${error.message}, ${error.stack}`; | |
} | |
return { | |
color: 'danger', | |
title, | |
message, | |
} as EffectParams<typeof showNotificationFx>; | |
}, | |
target: showNotificationFx, | |
}); | |
} | |
const { | |
useDirty, | |
useErrors, | |
useExternalErrors, | |
useField, | |
useFocused, | |
useForm, | |
useSubmitted, | |
useTouched, | |
useValue, | |
} = createReactLib({ validateOnUseForm: true }); | |
export { | |
createForm, | |
useDirty, | |
useErrors, | |
useExternalErrors, | |
useField, | |
useFocused, | |
useForm, | |
useSubmitted, | |
useTouched, | |
useValue, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment