Skip to content

Commit fff84b5

Browse files
authored
fix empty submissions (#10625)
1 parent 718ec1f commit fff84b5

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

packages/router/__tests__/router-test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11201,6 +11201,32 @@ describe("a router", () => {
1120111201
expect(await request.json()).toEqual(body);
1120211202
});
1120311203

11204+
it("serializes body as application/json if specified (null)", async () => {
11205+
let t = setup({
11206+
routes: [{ id: "root", path: "/", action: true }],
11207+
});
11208+
11209+
let body = null;
11210+
let F = await t.fetch("/", "key", {
11211+
formMethod: "post",
11212+
formEncType: "application/json",
11213+
body,
11214+
});
11215+
expect(t.router.state.fetchers.get("key")?.json).toBe(body);
11216+
await F.actions.root.resolve("ACTION");
11217+
11218+
expect(F.actions.root.stub).toHaveBeenCalledWith({
11219+
params: {},
11220+
request: expect.any(Request),
11221+
});
11222+
11223+
let request = F.actions.root.stub.mock.calls[0][0].request;
11224+
expect(request.method).toBe("POST");
11225+
expect(request.url).toBe("http://localhost/");
11226+
expect(request.headers.get("Content-Type")).toBe("application/json");
11227+
expect(await request.json()).toEqual(body);
11228+
});
11229+
1120411230
it("serializes body as text/plain if specified", async () => {
1120511231
let t = setup({
1120611232
routes: [{ id: "root", path: "/", action: true }],
@@ -11230,6 +11256,35 @@ describe("a router", () => {
1123011256
expect(await request.text()).toEqual(body);
1123111257
});
1123211258

11259+
it("serializes body as text/plain if specified (empty string)", async () => {
11260+
let t = setup({
11261+
routes: [{ id: "root", path: "/", action: true }],
11262+
});
11263+
11264+
let body = "";
11265+
let F = await t.fetch("/", "key", {
11266+
formMethod: "post",
11267+
formEncType: "text/plain",
11268+
body,
11269+
});
11270+
expect(t.router.state.fetchers.get("key")?.text).toBe(body);
11271+
11272+
await F.actions.root.resolve("ACTION");
11273+
11274+
expect(F.actions.root.stub).toHaveBeenCalledWith({
11275+
params: {},
11276+
request: expect.any(Request),
11277+
});
11278+
11279+
let request = F.actions.root.stub.mock.calls[0][0].request;
11280+
expect(request.method).toBe("POST");
11281+
expect(request.url).toBe("http://localhost/");
11282+
expect(request.headers.get("Content-Type")).toBe(
11283+
"text/plain;charset=UTF-8"
11284+
);
11285+
expect(await request.text()).toEqual(body);
11286+
});
11287+
1123311288
it("serializes body when encType=undefined", async () => {
1123411289
let t = setup({
1123511290
routes: [{ id: "root", path: "/", action: true }],

packages/router/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3145,7 +3145,7 @@ function normalizeNavigateOptions(
31453145
: (rawFormMethod.toLowerCase() as FormMethod);
31463146
let formAction = stripHashFromPath(path);
31473147

3148-
if (opts.body) {
3148+
if (opts.body !== undefined) {
31493149
if (opts.formEncType === "text/plain") {
31503150
// text only support POST/PUT/PATCH/DELETE submissions
31513151
if (!isMutationMethod(formMethod)) {

0 commit comments

Comments
 (0)