Skip to content

Commit a732d30

Browse files
dummdidummteemingc
authored andcommitted
fix: server-render nested form value sets (sveltejs#15378)
Fixes sveltejs#15327 - make getter lazy instead of snapshotting once in advance, so we can deal with updates to the fields - deep_set is a "do-something" function that does not return something, but in the mutation case we just assigned the result of the function (which is undefined) to the input. Fixed accordingly Co-authored-by: Tee Ming <chewteeming01@gmail.com>
1 parent bf7c4e2 commit a732d30

File tree

5 files changed

+48
-8
lines changed

5 files changed

+48
-8
lines changed

.changeset/nasty-donuts-read.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: server-render nested form value sets

packages/kit/src/runtime/app/server/remote/form.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,24 +176,28 @@ export function form(validate_or_fn, maybe_fn) {
176176

177177
Object.defineProperty(instance, 'fields', {
178178
get() {
179-
const data = get_cache(__)?.[''];
180-
const issues = flatten_issues(data?.issues ?? []);
181-
182179
return create_field_proxy(
183180
{},
184-
() => data?.input ?? {},
181+
() => get_cache(__)?.['']?.input ?? {},
185182
(path, value) => {
183+
const cache = get_cache(__);
184+
const data = cache[''];
185+
186186
if (data?.submission) {
187187
// don't override a submission
188188
return;
189189
}
190190

191-
const input =
192-
path.length === 0 ? value : deep_set(data?.input ?? {}, path.map(String), value);
191+
if (path.length === 0) {
192+
(cache[''] ??= {}).input = value;
193+
return;
194+
}
193195

194-
(get_cache(__)[''] ??= {}).input = input;
196+
const input = data?.input ?? {};
197+
deep_set(input, path.map(String), value);
198+
(cache[''] ??= {}).input = input;
195199
},
196-
() => issues
200+
() => flatten_issues(get_cache(__)?.['']?.issues ?? [])
197201
);
198202
}
199203
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
import { editData } from './form.remote';
3+
4+
const form = editData;
5+
form.fields.set({ description: 'ssr' });
6+
form.fields.description.set('nested');
7+
</script>
8+
9+
<div id="description">Description: {form.fields.description.value()}</div>
10+
11+
<form {...form}>
12+
<input {...form.fields.name.as('text')} />
13+
<button type="submit">Submit</button>
14+
</form>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { form } from '$app/server';
2+
import * as v from 'valibot';
3+
4+
export const editData = form(
5+
v.object({
6+
name: v.optional(v.string()),
7+
description: v.optional(v.string())
8+
}),
9+
async (data) => {
10+
return data;
11+
}
12+
);

packages/kit/test/apps/async/test/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,11 @@ test.describe('remote functions', () => {
490490
expect(JSON.parse(arrayValue)).toEqual([{ leaf: 'array-0-leaf' }, { leaf: 'array-1-leaf' }]);
491491
});
492492

493+
test('nested field set is SSR rendered', async ({ page }) => {
494+
await page.goto('/remote/form/set-ssr');
495+
await expect(page.locator('#description')).toHaveText('Description: nested');
496+
});
497+
493498
test('selects are not nuked when unrelated controls change', async ({
494499
page,
495500
javaScriptEnabled

0 commit comments

Comments
 (0)