Skip to content

Fix useSubmission/useSubmissions and action docs #1179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2eb5a34
Fix useSubmission
amirhhashemi May 16, 2025
b81537d
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] May 16, 2025
9443486
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] May 23, 2025
5db61a9
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] May 26, 2025
6092636
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] May 30, 2025
3285216
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] May 30, 2025
0d62686
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 1, 2025
7cbd617
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 1, 2025
67fb057
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 3, 2025
61acf4e
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 3, 2025
5c7b8da
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 7, 2025
cb9b4d8
Update
amirhhashemi Jun 8, 2025
bb52bf8
Update
amirhhashemi Jun 11, 2025
aa3f69d
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 11, 2025
fa8746c
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 11, 2025
26ee013
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 11, 2025
58abb2e
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 14, 2025
2c11ddf
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 14, 2025
954f116
Merge branch 'main' into fix-use-submission-situation
kodiakhq[bot] Jun 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update
  • Loading branch information
amirhhashemi committed Jun 8, 2025
commit cb9b4d80e3e7873b042c724b4881fe1addf689bb
31 changes: 17 additions & 14 deletions src/routes/solid-router/reference/data-apis/use-submission.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
title: useSubmission
---

The `useSubmission` function returns a submission object for a specified action.
This submission object contains properties to access the state of action execution and functions to control the action.
The `useSubmission` function retrieves the state of the most recent submission for a given action.

```tsx
import { Show } from "solid-js";
Expand Down Expand Up @@ -37,15 +36,14 @@ function AddTodoForm() {
```

:::info[Note]
If an action is executed multiple times, the last submission will be returned.
To access all submissions, `useSubmissions`[/solid-router/reference/data-apis/use-submissions] can be used.
To access the state of all submissions, `useSubmissions`[/solid-router/reference/data-apis/use-submissions] can be used.
:::

## Filter function

Optionally, `useSubmission` accepts a second parameter, which is a filter function.
This function is executed for each submission and returns the first submission that passes through the filter.
The filter function takes the submitted data as its parameter and should return `true` to select the submission and `false` otherwise.
The `useSubmission` function optionally accepts a second parameter, which is a filter function.
This function is executed for each submission in the order they were created, and the first submission that meet the filter criteria is returned by `useSubmission`.
The filter function recieves the input data of the action as its parameter and must return `true` to select the submission or `false` otherwise.

```tsx
import { useSubmission } from "@solidjs/router";
Expand All @@ -59,23 +57,28 @@ function LatestTodo() {
return name.length > 2;
}
);
return <p>Latest valid submittion: {latestValidSubmission.result}</p>;
return <p>Latest valid submission: {latestValidSubmission.result}</p>;
}
```

## Parameters

- **action**: The action for which you want to return submissions.
- **filter** (Optional): The filter function that receives the submitted data as its parameter.
It should return `true` if the submission passes the filter and `false` otherwise.
- **action**: The action for which you want to get the most recent submission.
- **filter** (optional): A filter function.
When provided, it executes on each submission in the order of creation, returning the first submission that passes the filter.
It receives the input data of the action as its parameter and must return `true` for the submission to be selected and `false` otherwise.

## Returns

`useSubmission` returns an object containing the following properties:

- **input**: The input data of the action.
- **result**: The returned value of the action.
This is a reactive value.
- **result**: The value returned from the action.
This is a reactive value.
- **error**: Any error thrown from the action.
This is a reactive value.
- **pending**: A boolean indicating whether the action is currently being executed.
- **clear**: A function to clear the results of the submission.
- **retry**: A function to re-execute the action.
This is a reactive value.
- **clear**: A function that clears the result of the submission.
- **retry**: A function that re-executes the submission with the same input.
264 changes: 93 additions & 171 deletions src/routes/solid-router/reference/data-apis/use-submissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,189 +2,111 @@
title: useSubmissions
---

This helper is used to handle form submissions and can provide optimistic updates while actions are in flight as well as pending state feedback.
This method will return an iterable of all submitted actions while its component is mounted. With an optional second parameter for a filter function.

:::tip
If you only care for the latest submission, you can use the [`useSubmission`](/solid-router/reference/data-apis/use-submission) helper.
:::

It's important to note that it requires the form method to be **post** otherwise it will trigger a browser navigation and will not work.

In the example below, the `useSubmissions` helper is used to retain a list of all submission results to that action while also giving feedback on the pending state of the current in-flight submission.

```tsx title="component.tsx" {4,9-20, 23}
import { useSubmissions } from "@solidjs/router";

function Component() {
const submissions = useSubmissions(postNameAction);

return (
<form method="post" action={postNameAction}>
<ul>
<For each={Array.from(submissions.entries())}>
{([attemptIndex, data]) => (
<Show when={data.result}>
{ result => (
<li>
Backend {attemptIndex}: {result.name}
</li>
)}
</Show>
</>
)}
</For>
</ul>
<input name="name" type="text" />
<button type="submit">{submissions.pending ? "sending" : "send"}</button>
</form>
)
The `useSubmissions` function retrieves the state of all submissions for a given action.

```tsx
import { For, Show } from "solid-js";
import { action, useSubmissions } from "@solidjs/router";

const addTodoAction = action(async (formData: FormData) => {
const name = formData.get("name")?.toString() ?? "";
if (name.length <= 2) {
throw new Error("Name must be larger than 2 characters");
}
return name;
}, "addTodo");

export default function AddTodoForm() {
const submissions = useSubmissions(addTodoAction);
return (
<div>
<form action={addTodoAction} method="post">
<input name="name" />
<button type="submit">Add</button>
</form>
<For each={submissions}>
{(submission) => (
<div>
<span>Adding "{submission.input[0].get("name")?.toString()}"</span>
<Show when={submission.pending}>
<span> (pending...)</span>
</Show>
<Show when={submission.result}>
<span> (completed)</span>
</Show>
<Show when={submission.error}>
{(error) => (
<>
<span>{` (Error: ${error().message})`}</span>
<button onClick={() => submission.retry()}>Retry</button>
</>
)}
</Show>
</div>
)}
</For>
</div>
);
}
```

:::info
To trigger a submission, [actions](https://docs.solidjs.com/) can be used.
:::info[Note]
To access the state of the most recent submission, `useSubmission`[/solid-router/reference/data-apis/use-submission] can be used.
:::

## Filtering Submissions
## Filter function

As an optional second parameter, the `useSubmissions` helper can receive a filter function to only return the submission that matches the condition.
The filter receives the submitted dated as a parameter and should return a boolean value.
E.g.: action below will only submit if the name is "solid".
The `useSubmissions` function optionally accepts a second parameter, which is a filter function.
This function is executed for each submission in the order they were created, and only the submissions that meet the filter criteria are returned by `useSubmissions`.
The filter function recieves the input data of the action as its parameter and must return `true` to select the submission or `false` otherwise.

```tsx title="component.tsx" {4-8}
```tsx
import { useSubmissions } from "@solidjs/router";

function Component() {
const submissions = useSubmissions(postNameAction, ([formData]) => {
const name = formData.get("name") ?? "";

return name === "solid";
});

return (
<form method="post" action={postNameAction}>
<ul>
<For each={Array.from(submissions.entries())}>
{([attemptIndex, data]) => (
<Show when={data.result}>
{ result => (
<li>
Backend {attemptIndex}: {result.name}
</li>
)}
</Show>
</>
)}
</For>
</ul>
<input name="name" type="text" />
<button type="submit">{submissions.pending ? "sending" : "send"}</button>
</form>
)
import { addTodoAction } from "./actions";

function FailedTodos() {
const failedSubmissions = useSubmissions(
addTodoAction,
([formData]: [FormData]) => {
const name = formData.get("name")?.toString() ?? "";
return name.length <= 2;
}
);
return (
<div>
<p>Failed submissions:</p>
<For each={failedSubmissions}>
{(submission) => (
<div>
<span>{submission.input[0].get("name")?.toString()}</span>
<button onClick={() => submission.retry()}>Retry</button>
</div>
)}
</For>
</div>
);
}
```

## Optimistic Updates

When the form is submitted, the `submission` object will be updated with the new value and the `pending` property will be set to `true`.
This allows you to provide feedback to the user that the action is in progress.
Once the action is complete, the `pending` property will be set to `false` and the `result` property will be updated with final value.
## Parameters

```tsx tab title="TypeScript" {6,13-20}
// component.tsx
import { Show } from "solid-js";
import { useSubmissions } from "@solidjs/router";

function Component() {
const submissions = useSubmissions(postNameAction);
- **action**: The action for which you want to get the submissions.
- **filter** (optional): A filter function.
When provided, it executes on each submission in the order of creation, returning the submissions that pass the filter.
It receives the input data of the action as its parameter and must return `true` to select the submission and `false` otherwise.

return (
<form method="post" action={postNameAction}>
<ul>
<For each={Array.from(submissions.entries())}>
{([attemptIndex, data]) => (
<Show when={data.input[0].entries().next()}>
{(input) => {
const name = (input().value as [string, string])[1]
## Returns

return (
<li>Optimistic: {name}</li>
)}}
</Show>
)}
</For>
</ul>
<input name="name" type="text" />
<button type="submit">{submissions.pending ? "sending" : "send"}</button>
</form>
)
}
```
`useSubmissions` returns an array of submissions.
Each submission is an object containing the following properties:

```tsx tab title="JavaScript" {6,13-20}
// component.jsx
import { Show } from "solid-js";
import { useSubmissions } from "@solidjs/router";

function Component() {
const submissions = useSubmissions(postNameAction);

return (
<form method="post" action={postNameAction}>
<ul>
<For each={Array.from(submissions.entries())}>
{([attemptIndex, data]) => (
<Show when={data.input[0].entries().next()}>
{(input) => {
const name = input().value[1]

return (
<li>Optimistic: {name}</li>
)}}
</Show>
)}
</For>
</ul>
<input name="name" type="text" />
<button type="submit">{submissions.pending ? "sending" : "send"}</button>
</form>
)
}
```

## Error Handling

If the action fails, the `submission` object will be updated with the error and the `pending` property will be set to `false`.
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.

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.

```tsx title="component.tsx" {12-18}
import { Show } from "solid-js";
import { useSubmissions } from "@solidjs/router";

function Component() {
const submissions = useSubmissions(postNameAction);

return (
<form method="post" action={postNameAction}>
<ul>
<For each={Array.from(submissions.entries())}>
{([attempt, data]) => (
<Show when={data.error}>
<li>
<p>Backend {attempt}: {data.error.message}</p>
<button onClick={() => data.retry()}>retry</button>
<button onClick={() => data.clear()}>clear</button>
</li>
</Show>
)}
</For>
</ul>
<input name="name" type="text" required autocomplete="off" />
<button type="submit">{submissions.pending ? "sending" : "send"}</button>
</form>
)
}
```
- **input**: The input data of the action.
This is a reactive value.
- **result**: The value returned from the action.
This is a reactive value.
- **error**: Any error thrown from the action.
This is a reactive value.
- **pending**: A boolean indicating whether the action is currently being executed.
This is a reactive value.
- **clear**: A function that clears the result of the submission.
- **retry**: A function that re-executes the submission with the same input.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy