Skip to content
51 changes: 51 additions & 0 deletions docs/reference/classes/formapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,57 @@ Defined in: [packages/form-core/src/FormApi.ts:1661](https://github.com/TanStack

***

### getAllErrors()

```ts
getAllErrors(): object
```

Defined in: [packages/form-core/src/FormApi.ts:1872](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1872)

Returns form and field level errors

#### Returns

`object`

##### fields

```ts
fields: Record<string, {
errorMap: ValidationErrorMap;
errors: unknown[];
}>;
```

##### form

```ts
form: object;
```

###### form.errorMap

```ts
errorMap: Record<"onChange" | "onBlur" | "onSubmit" | "onMount" | "onServer", unknown>;
```

###### form.errors

```ts
errors: (
| UnwrapFormValidateOrFn<TOnMount>
| UnwrapFormValidateOrFn<TOnChange>
| UnwrapFormAsyncValidateOrFn<TOnChangeAsync>
| UnwrapFormValidateOrFn<TOnBlur>
| UnwrapFormAsyncValidateOrFn<TOnBlurAsync>
| UnwrapFormValidateOrFn<TOnSubmit>
| UnwrapFormAsyncValidateOrFn<TOnSubmitAsync>
| UnwrapFormAsyncValidateOrFn<TOnServer>)[];
```

***

### getFieldInfo()

```ts
Expand Down
49 changes: 49 additions & 0 deletions packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,55 @@ export class FormApi<
}) as never,
)
}

/**
* Returns form and field level errors
*/
getAllErrors = () => {
const reduceErrorMap = (errorMap: ValidationErrorMap) => {
return Object.entries(errorMap).reduce(
(errorAcc, [errorName, errorValue]) => {
if (errorValue != null) {
errorAcc[errorName as ValidationErrorMapKeys] = errorValue
}

return errorAcc
},
{} as Record<ValidationErrorMapKeys, ValidationError>,
)
}

return {
form: {
errors: this.state.errors,
errorMap: reduceErrorMap(this.state.errorMap),
},
fields: Object.entries(this.state.fieldMeta).reduce(
(acc, [fieldName, fieldMeta]) => {
// reduces error map down to keys with errors
const fieldErrors = reduceErrorMap(
(fieldMeta as AnyFieldMeta).errorMap,
)

if (
Object.keys(fieldErrors).length &&
(fieldMeta as AnyFieldMeta).errors.length
) {
acc[fieldName] = {
errors: (fieldMeta as AnyFieldMeta).errors,
errorMap: fieldErrors,
}
}

return acc
},
{} as Record<
string,
{ errors: ValidationError[]; errorMap: ValidationErrorMap }
>,
),
}
}
}

function normalizeError<TFormData>(rawError?: FormValidationError<unknown>): {
Expand Down
55 changes: 55 additions & 0 deletions packages/form-core/tests/FormApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,61 @@ describe('form api', () => {
})
})

it('should return all errors', () => {
const form = new FormApi({
defaultValues: {
name: 'other',
age: 'hi',
},
validators: {
onChange: ({ value }) => {
if (value.name === 'other') return 'onChange - form'
return
},
onMount: ({ value }) => {
if (value.name === 'other') return 'onMount - form'
return
},
},
})
const field = new FieldApi({
form,
name: 'name',
validators: {
onChange: ({ value }) => {
if (value === 'other') {
return 'onChange - field'
}
return
},
},
})

form.mount()
field.mount()
expect(form.getAllErrors()).toEqual({
fields: {},
form: {
errors: ['onMount - form'],
errorMap: { onMount: 'onMount - form' },
},
})

field.setValue('other')
expect(form.getAllErrors()).toStrictEqual({
fields: {
name: {
errors: ['onChange - field'],
errorMap: { onChange: 'onChange - field' },
},
},
form: {
errors: ['onChange - form'],
errorMap: { onChange: 'onChange - form' },
},
})
})

it('should reset onChange errors when the issue is resolved', () => {
const form = new FormApi({
defaultValues: {
Expand Down