Skip to content
Open
7 changes: 6 additions & 1 deletion packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2249,6 +2249,7 @@ export class FormApi<
const dontUpdateMeta = opts?.dontUpdateMeta ?? false
const dontRunListeners = opts?.dontRunListeners ?? false
const dontValidate = opts?.dontValidate ?? false
const isFile = updater instanceof File

batch(() => {
if (!dontUpdateMeta) {
Expand All @@ -2267,7 +2268,11 @@ export class FormApi<
this.baseStore.setState((prev) => {
return {
...prev,
values: setBy(prev.values, field, updater),
values: setBy(
prev.values,
field,
isFile ? { file: updater, uuid: uuid() } : updater,
),
}
})
})
Expand Down
31 changes: 31 additions & 0 deletions packages/form-core/tests/FormApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4096,6 +4096,37 @@ it('should generate a formId if not provided', () => {
expect(form.formId.length).toBeGreaterThan(1)
})

it('it should set a file value with uuid when setting a field value with File', () => {
const form = new FormApi({
defaultValues: {
avatar: undefined,
} as { avatar: unknown },
})

form.mount()

const firstFile = new File(['first'], 'first.png', { type: 'image/png' })
form.setFieldValue('avatar', firstFile)

const firstValue = form.state.values.avatar as { file: File; uuid: string }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These type assertions are a huge problem. It cannot stay.

Luckily, as long as evaluate properly handles File types, this whole uuid trickery won't be needed. Just make sure to add unit tests for a File comparison with evaluate. I believe the existing tests can be found in utils.spec.ts.


expect(firstValue).toBeDefined()
expect(firstValue.file instanceof File).toBe(true)
expect(firstValue.file.name).toBe('first.png')
expect(typeof firstValue.uuid).toBe('string')
expect(firstValue.uuid.length > 0).toBe(true)

const secondFile = new File(['second'], 'second.png', { type: 'image/png' })
form.setFieldValue('avatar', secondFile)

const secondValue = form.state.values.avatar as { file: File; uuid: string }

expect(secondValue.file.name).toBe('second.png')
expect(typeof secondValue.uuid).toBe('string')
expect(secondValue.uuid.length > 0).toBe(true)
expect(secondValue.uuid).not.toBe(firstValue.uuid)
})

describe('form api event client', () => {
it('should have debug disabled', () => {
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
Expand Down