Skip to content

Commit 90eafba

Browse files
authored
fix: clear issues upon passing validation (#14683)
Fixes #14646
1 parent f3e3126 commit 90eafba

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

.changeset/busy-planes-cover.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: clear issues upon passing validation

packages/kit/src/runtime/client/remote-functions/form.svelte.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ export function form(id) {
203203

204204
const form_result = /** @type { RemoteFunctionResponse} */ (await response.json());
205205

206+
// reset issues in case it's a redirect or error (but issues passed in that case)
207+
raw_issues = [];
208+
206209
if (form_result.type === 'result') {
207210
({ issues: raw_issues = [], result } = devalue.parse(form_result.result, app.decoders));
208211

packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import { issue_path_form, my_form } from './form.remote.js';
2+
import { issue_path_form, my_form, my_form_2 } from './form.remote.js';
33
import * as v from 'valibot';
44
55
const schema = v.object({
@@ -8,7 +8,7 @@
88
button: v.optional(v.literal('submitter'))
99
});
1010
let submitter;
11-
$inspect(my_form.fields.allIssues());
11+
let error = $state(false);
1212
</script>
1313

1414
<form id="my-form" {...my_form.preflight(schema)} oninput={() => my_form.validate()}>
@@ -33,6 +33,7 @@
3333
<p>{issue.message}</p>
3434
{/each}
3535
</form>
36+
3637
<button
3738
id="trigger-validate"
3839
onclick={() => my_form.validate({ includeUntouched: true, submitter })}
@@ -51,3 +52,25 @@
5152
</button>
5253
<pre id="allIssues">{JSON.stringify(issue_path_form.fields.allIssues())}</pre>
5354
</form>
55+
56+
<form
57+
id="my-form-2"
58+
{...my_form_2.enhance(async ({ submit }) => {
59+
error = false;
60+
try {
61+
await submit();
62+
} catch {
63+
error = true;
64+
}
65+
})}
66+
>
67+
{#each my_form_2.fields.baz.issues() as issue}
68+
<p>{issue.message}</p>
69+
{/each}
70+
71+
<input {...my_form_2.fields.baz.as('text')} />
72+
73+
<p data-error>{error ? 'An error occurred' : 'No error'}</p>
74+
75+
<button>submit</button>
76+
</form>

packages/kit/test/apps/basics/src/routes/remote/form/validate/form.remote.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { form } from '$app/server';
2+
import { error } from '@sveltejs/kit';
23
import * as v from 'valibot';
34

45
export const my_form = form(
@@ -17,6 +18,15 @@ export const my_form = form(
1718
}
1819
);
1920

21+
export const my_form_2 = form(
22+
v.object({
23+
baz: v.picklist(['a', 'b'])
24+
}),
25+
async ({ baz }) => {
26+
if (baz === 'a') error(400, 'Nope');
27+
}
28+
);
29+
2030
export const issue_path_form = form(
2131
v.object({
2232
nested: v.object({

packages/kit/test/apps/basics/test/test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,33 @@ test.describe('remote functions', () => {
19051905
await expect(allIssues).toContainText('"path":["nested","value"]');
19061906
});
19071907

1908+
test('form validation issues cleared', async ({ page, javaScriptEnabled }) => {
1909+
if (!javaScriptEnabled) return;
1910+
1911+
await page.goto('/remote/form/validate');
1912+
1913+
const baz = page.locator('input[name="baz"]');
1914+
const submit = page.locator('#my-form-2 button');
1915+
1916+
await baz.fill('c');
1917+
await submit.click();
1918+
await expect(page.locator('#my-form-2')).toContainText('Invalid type: Expected');
1919+
1920+
await baz.fill('a');
1921+
await submit.click();
1922+
await expect(page.locator('#my-form-2')).not.toContainText('Invalid type: Expected');
1923+
await expect(page.locator('[data-error]')).toHaveText('An error occurred');
1924+
1925+
await baz.fill('c');
1926+
await submit.click();
1927+
await expect(page.locator('#my-form-2')).toContainText('Invalid type: Expected');
1928+
1929+
await baz.fill('b');
1930+
await submit.click();
1931+
await expect(page.locator('#my-form-2')).not.toContainText('Invalid type: Expected');
1932+
await expect(page.locator('[data-error]')).toHaveText('No error');
1933+
});
1934+
19081935
test('form inputs excludes underscore-prefixed fields', async ({ page, javaScriptEnabled }) => {
19091936
if (javaScriptEnabled) return;
19101937

0 commit comments

Comments
 (0)