Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/shared/config/errors/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface DefaultError {

type LocationTypeError = 'body' | 'query';

interface FormFieldError extends DefaultError {
export interface FormFieldError extends DefaultError {
location: [Extract<LocationTypeError, 'body'>, string];
}

Expand Down
21 changes: 3 additions & 18 deletions src/shared/ui/ManagedForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { checkIsFormFieldsError, getErrorMessage } from '@shared/config';

import classes from './styles.module.less';
import { ManagedFormProps } from './types';
import { cleanErrors, showErrorsInFields } from './utils';

/** Form component to manage the request and results of a form request */
export const ManagedForm = <T extends object, R>({
Expand Down Expand Up @@ -49,11 +50,7 @@ export const ManagedForm = <T extends object, R>({

if (checkIsFormFieldsError(error) && error.response) {
message = 'Form error has occurred';
const fieldErrors = error.response.data.error.details.map((field) => ({
name: field.location[1],
errors: [field.message],
}));
form.setFields(fieldErrors);
showErrorsInFields(form, error.response.data.error.details);
}

notification.error({
Expand All @@ -63,20 +60,8 @@ export const ManagedForm = <T extends object, R>({
});
};

// Clean error from backend after field change value
const onValuesChange = (values: T) => {
Object.keys(values).forEach((field) => {
const error = form.getFieldError(field);
if (!error.length) {
return;
}
form.setFields([
{
name: field,
errors: [],
},
]);
});
cleanErrors(form, values);
};

return (
Expand Down
28 changes: 28 additions & 0 deletions src/shared/ui/ManagedForm/utils/cleanErrors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FormInstance } from 'antd';

/**
* Util for cleaning field error text from backend while change its value
*
* @param form - Form instance.
* @param values - Form values that have changed.
*
*/
export const cleanErrors = (form: FormInstance, values: object, parentPath: string[] = []): void => {
Object.entries(values).forEach(([key, value]) => {
const currentPath = [...parentPath, key];

if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
cleanErrors(form, value, currentPath);
return;
}
const error = form.getFieldError(currentPath);
if (error.length) {
form.setFields([
{
name: currentPath,
errors: [],
},
]);
}
});
};
2 changes: 2 additions & 0 deletions src/shared/ui/ManagedForm/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './cleanErrors';
export * from './showErrorsInFields';
33 changes: 33 additions & 0 deletions src/shared/ui/ManagedForm/utils/showErrorsInFields/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FormFieldError } from '@shared/config';
import { FormInstance } from 'antd';

/**
* Util for processing and displaying form field errors from backend
*
* @param form - Form instance
* @param errors - Array of objects with paths to fields contains an error from backend
*
*/
export const showErrorsInFields = (form: FormInstance, errors: FormFieldError[]): void => {
const fieldErrors = errors
.map((field) => {
// Keep only valid parts of the path
const validPath = field.location.reduce<string[]>((acc, key) => {
const currentPath = [...acc, key];
// Check if the path to the current key exists
if (typeof form.getFieldValue(currentPath) === 'object' || form.getFieldInstance(currentPath)) {
acc.push(key);
}
return acc;
}, []);

return {
name: validPath,
errors: [field.message],
};
})
// Remove errors without a valid path
.filter(({ name }) => name.length > 0);

form.setFields(fieldErrors);
};
Loading