Skip to content

Instantly share code, notes, and snippets.

@7iomka
Created February 28, 2023 21:04
Show Gist options
  • Save 7iomka/3304ff1f59961426cf8a070ada6ce876 to your computer and use it in GitHub Desktop.
Save 7iomka/3304ff1f59961426cf8a070ada6ce876 to your computer and use it in GitHub Desktop.
Factory example
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