Skip to content

Commit 2eb5a34

Browse files
committed
Fix useSubmission
1 parent 29603cb commit 2eb5a34

File tree

1 file changed

+61
-141
lines changed

1 file changed

+61
-141
lines changed

src/routes/solid-router/reference/data-apis/use-submission.mdx

Lines changed: 61 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -2,160 +2,80 @@
22
title: useSubmission
33
---
44

5-
This helper is used to handle form submissions and can provide optimistic updates while actions are in flight as well as pending state feedback.
6-
This method will return a single (latest) value while its sibling, [`useSubmissions`](/solid-router/reference/data-apis/use-submissions), will return all values submitted while the component is active. With an optional second parameter for a filter function.
5+
The `useSubmission` function returns a submission object for a specified action.
6+
This submission object contains properties to access the state of action execution and functions to control the action.
77

8-
It's important to note that `useSubmission` requires the form method to be **post** otherwise it will trigger a browser navigation and will not work.
9-
10-
```tsx title="component.tsx" {4,8}
11-
import { useSubmission } from "@solidjs/router";
12-
13-
function Component() {
14-
const submission = useSubmission(postNameAction);
15-
16-
return (
17-
<form action={postNameAction} method="post">
18-
<input type="text" name="name" />
19-
<button type="submit">
20-
{submission.pending ? "Adding..." : "Add"}
21-
</button>
22-
</form>
23-
)
8+
```tsx
9+
import { Show } from "solid-js";
10+
import { action, useSubmission } from "@solidjs/router";
11+
12+
const addTodoAction = action(async (formData: FormData) => {
13+
const name = formData.get("name")?.toString() ?? "";
14+
if (name.length <= 2) {
15+
throw new Error("Name must be larger than 2 characters");
16+
}
17+
}, "addTodo");
18+
19+
function AddTodoForm() {
20+
const submission = useSubmission(addTodoAction);
21+
return (
22+
<form action={addTodoAction} method="post">
23+
<input name="name" />
24+
<button type="submit">{submission.pending ? "Adding..." : "Add"}</button>
25+
<Show when={submission.error}>
26+
{(error) => (
27+
<div>
28+
<p>{error().message}</p>
29+
<button onClick={() => submission.clear()}>Clear</button>
30+
<button onClick={() => submission.retry()}>Retry</button>
31+
</div>
32+
)}
33+
</Show>
34+
</form>
35+
);
2436
}
2537
```
2638

27-
:::info
28-
Learn more about actions in the [`action`](/solid-router/reference/data-apis/action) docs.
39+
:::info[Note]
40+
If an action is executed multiple times, the last submission will be returned.
41+
To access all submissions, `useSubmissions`[/solid-router/reference/data-apis/use-submissions] can be used.
2942
:::
3043

31-
## Filtering Submissions
32-
33-
As an optional second parameter, the `useSubmission` helper can receive a filter function to only return the submission that matches the condition.
34-
The filter receives the submitted dated as a parameter and should return a boolean value.
35-
E.g.: action below will only submit if the name is "solid".
36-
37-
```tsx title="component.tsx" {4-8}
38-
import { useSubmission } from "@solidjs/router";
39-
40-
function Component() {
41-
const submission = useSubmission(postNameAction, ([formData]) => {
42-
const name = formData.get("name") ?? "";
43-
44-
return name === "solid";
45-
});
46-
47-
return (
48-
<form action={postNameAction} method="post">
49-
<input type="text" name="name" />
50-
<button type="submit">
51-
{submission.pending ? "Adding..." : "Add"}
52-
</button>
53-
</form>
54-
)
55-
}
56-
```
57-
58-
## Optimistic Updates
59-
60-
When the form is submitted, the `submission` object will be updated with the new value and the `pending` property will be set to `true`.
61-
This allows you to provide feedback to the user that the action is in progress.
62-
Once the action is complete, the `pending` property will be set to `false` and the `result` property will be updated with final value.
63-
64-
```tsx tab title="TypeScript" {6,10-12}
65-
// component.tsx
66-
import { Show } from "solid-js";
67-
import { useSubmission } from "@solidjs/router";
68-
69-
function Component() {
70-
const submission = useSubmission(postNameAction);
71-
72-
return (
73-
<>
74-
<Show when={submission.input?.[0].get("name")}>
75-
{(name) => <div>Optimistic: {name() as string}</div>}
76-
</Show>
44+
## Filter function
7745

78-
<Show when={submission.result?.name}>
79-
{(name) => <div>Result: {name()}</div>}
80-
</Show>
46+
Optionally, `useSubmission` accepts a second parameter, which is a filter function.
47+
This function is executed for each submission and returns the first submission that passes through the filter.
48+
The filter function takes the submitted data as its parameter and should return `true` to select the submission and `false` otherwise.
8149

82-
<form method="post" action={sendData}>
83-
<input type="text" name="name" required />
84-
<button type="submit" disabled={submission.pending}>
85-
{submission.pending ? "Submitting" : "Submit"}
86-
</button>
87-
</form>
88-
</>
89-
)
90-
}
91-
```
92-
93-
```tsx tab title="JavaScript" {6,10-12}
94-
// component.jsx
95-
import { Show } from "solid-js";
50+
```tsx
9651
import { useSubmission } from "@solidjs/router";
97-
98-
function Component() {
99-
const submission = useSubmission(postNameAction);
100-
101-
return (
102-
<>
103-
<Show when={submission.input?.[0].get("name")}>
104-
{(name) => <div>Optimistic: {name()}</div>}
105-
</Show>
106-
107-
<Show when={submission.result?.name}>
108-
{(name) => <div>Result: {name()}</div>}
109-
</Show>
110-
111-
<form method="post" action={sendData}>
112-
<input type="text" name="name" required />
113-
<button type="submit" disabled={submission.pending}>
114-
{submission.pending ? "Submitting" : "Submit"}
115-
</button>
116-
</form>
117-
</>
118-
)
52+
import { addTodoAction } from "./actions";
53+
54+
function LatestTodo() {
55+
const latestValidSubmission = useSubmission(
56+
addTodoAction,
57+
([formData]: [FormData]) => {
58+
const name = formData.get("name")?.toString() ?? "";
59+
return name.length > 2;
60+
}
61+
);
62+
return <p>Latest valid submittion: {latestValidSubmission.result}</p>;
11963
}
12064
```
12165

122-
## Error Handling
123-
124-
If the action fails, the `submission` object will be updated with the error and the `pending` property will be set to `false`.
125-
This allows you to provide feedback to the user that the action has failed. Additionally, the return type of `useSubmission` will have a new key `error` that will contain the error object thrown by the submission handler.
126-
127-
At this stage, you can also use the `retry()` method to attempt the action again or the `clear()` to wipe the filled data in the platform.
66+
## Parameters
12867

129-
```tsx title="component.tsx" {12-18}
130-
import { Show } from "solid-js";
131-
import { useSubmission } from "@solidjs/router";
68+
- **action**: The action for which you want to return submissions.
69+
- **filter** (Optional): The filter function that receives the submitted data as its parameter.
70+
It should return `true` if the submission passes the filter and `false` otherwise.
13271

133-
function Component() {
134-
const submission = useSubmission(postNameAction);
72+
## Returns
13573

136-
return (
137-
<>
138-
<Show when={submission.error}>
139-
{(error) => (
140-
<div>
141-
<p>Error: {error.message}</p>
142-
<button onClick={() => submission.clear()}>
143-
Clear
144-
</button>
145-
<button onClick={async () => submission.retry()}>
146-
Retry
147-
</button>
148-
</div>
149-
)}
150-
</Show>
74+
`useSubmission` returns an object containing the following properties:
15175

152-
<form method="post" action={sendData}>
153-
<input type="text" name="name" required />
154-
<button type="submit" disabled={submission.pending}>
155-
{submission.pending ? "Submitting" : "Submit"}
156-
</button>
157-
</form>
158-
</>
159-
)
160-
}
161-
```
76+
- **input**: The input data of the action.
77+
- **result**: The returned value of the action.
78+
- **error**: Any error thrown from the action.
79+
- **pending**: A boolean indicating whether the action is currently being executed.
80+
- **clear**: A function to clear the results of the submission.
81+
- **retry**: A function to re-execute the action.

0 commit comments

Comments
 (0)