Skip to content

Commit

Permalink
Form actions (sveltejs#6469)
Browse files Browse the repository at this point in the history
* basic actions method

* add form store

* remove export let errors in favor of form store

* make actions an object

* implement FilesFormData

* restrict values type, fix conversion, switch argument order

* validation->invalid

* start writing docs

* implement handleFile

* fix tests

* test for files

* complete migration message

* support validation error thrown in endpoints

* infer file type from handleFile hook

* add handleFile to build

* types, cleanup

* $form -> $submitted

* woops

* allow arbitrary data on invalid, persist data in success case

* fix infered FileType

* give JSON response a well-defined shape

* provide form state through form prop and $page.form

* return invalid instead of throwing it

* types for actions

* fix, skip test

* updateForm (simple version)

* making a start at enhance

* bye bye method overrides

* update create-svelte default template

* remove handleFile

* full blown enhance and updateForm through $app/forms

* fix type reference

* adjust default template

* remove $page.form for now (too much of a footgun due to resets)

* tests, ensure form is only reset on page changes

* ?????

* cleanup

* docs about multiple forms

* make docs build

* lint

* fix

* add toggle action

* rename generated FormData type to ActionData

* reset form on navigation, not invalidation

* silence missing/unused form prop warnings, DRY out code a bit

* Update packages/kit/src/runtime/server/page/actions.js

* Update packages/kit/src/runtime/server/page/actions.js

* Update packages/kit/src/runtime/server/page/actions.js

* change message to reference actions

* Update packages/kit/src/runtime/server/page/actions.js

* Update packages/kit/src/runtime/server/page/actions.js

* be more specific about what content-type is accepted

* Update packages/kit/src/runtime/server/page/render.js

* Update packages/kit/src/runtime/server/page/render.js

* unskip test

* fix types

* tweak enhance function and make todos example work again

* changeset

* deduplicate type usage

* lint

* wording, make updateForm (now applySubmissionResult) more powerful

* fix, docs

* applySubmissionResult -> applyAction

* change enhance function signature

* fix template

* fix template

* Update .changeset/spicy-pugs-applaud.md

* Update packages/kit/src/runtime/app/forms.js

* Apply suggestions from code review

* prettier

* rename SubmissionResult to ActionResult

* Update packages/kit/types/ambient.d.ts

* Update packages/kit/types/ambient.d.ts

* updateForm -> applyAction

* use RequestEvent instead of ActionEvent

* fix

* invalidate first, delegate redirect/error handling to applyAction

* remove token stuff, simplify a bit

* show +error page without reloading route

* check action return data can be serialized as JSON

* add note to render.js

* merge FetchFormResponse and ActionResult

* update docs

* remove logging

* tiny docs tweak

Co-authored-by: Rich Harris <[email protected]>
Co-authored-by: Rich Harris <[email protected]>
  • Loading branch information
3 people authored Sep 6, 2022
1 parent 4922e26 commit 2569518
Show file tree
Hide file tree
Showing 82 changed files with 1,603 additions and 788 deletions.
6 changes: 6 additions & 0 deletions .changeset/spicy-pugs-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'create-svelte': patch
'@sveltejs/kit': patch
---

[breaking] Replace `POST`/`PUT`/`PATCH`/`DELETE` in `+page.server.js` with `export const actions`
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"files": [
"**/CHANGELOG.md",
"**/.svelte-kit/**",
"documentation/**/*.md",
"packages/package/test/fixtures/**/expected/**/*",
"packages/package/test/watch/expected/**/*",
"packages/package/test/watch/package/**/*",
Expand Down
69 changes: 1 addition & 68 deletions documentation/docs/03-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,74 +112,7 @@ During client-side navigation, SvelteKit will load this data from the server, wh

Like `+page.js`, `+page.server.js` can export [page options](/docs/page-options)`prerender`, `ssr` and `csr`.

#### Actions

`+page.server.js` can also declare _actions_, which correspond to the `POST`, `PATCH`, `PUT` and `DELETE` HTTP methods. A request made to the page with one of these methods will invoke the corresponding action before rendering the page.

An action can return a `{ status?, errors }` object if there are validation errors (`status` defaults to `400`), or an optional `{ location }` object to redirect the user to another page:

```js
/// file: src/routes/login/+page.server.js

// @filename: ambient.d.ts
declare global {
const createSessionCookie: (userid: string) => string;
const hash: (content: string) => string;
const db: {
findUser: (name: string) => Promise<{
id: string;
username: string;
password: string;
}>
}
}

export {};

// @filename: index.js
// ---cut---
import { error } from '@sveltejs/kit';

/** @type {import('./$types').Action} */
export async function POST({ cookies, request, url }) {
const values = await request.formData();

const username = /** @type {string} */ (values.get('username'));
const password = /** @type {string} */ (values.get('password'));

const user = await db.findUser(username);

if (!user) {
return {
status: 403,
errors: {
username: 'No user with this username'
}
};
}

if (user.password !== hash(password)) {
return {
status: 403,
errors: {
password: 'Incorrect password'
}
};
}

cookies.set('sessionid', createSessionCookie(user.id), {
httpOnly: true
});

return {
location: url.searchParams.get('redirectTo') ?? '/'
};
}
```
If validation `errors` are returned, they will be available inside `+page.svelte` as `export let errors`.
> The actions API will likely change in the near future: https://github.com/sveltejs/kit/discussions/5875
A `+page.server.js` file can also export _actions_. If `load` lets you read data from the server, `actions` let you write data _to_ the server using the `<form>` element. To learn how to use them, see the [form actions](/docs/form-actions) section.

### +error

Expand Down
Loading

0 comments on commit 2569518

Please sign in to comment.