Skip to content

Instantly share code, notes, and snippets.

@Mlocik97
Created June 16, 2022 14:51
Show Gist options
  • Save Mlocik97/5230e19af795727f75ba9d08cef3b3fc to your computer and use it in GitHub Desktop.
Save Mlocik97/5230e19af795727f75ba9d08cef3b3fc to your computer and use it in GitHub Desktop.
import { invalidate } from '$app/navigation';
// this action (https://svelte.dev/tutorial/actions) allows us to
// progressively enhance a <form> that already works without JS
/**
* @param {HTMLFormElement} form
* @param {{
* pending?: ({ data, form }: { data: FormData; form: HTMLFormElement }) => void;
* error?: ({
* data,
* form,
* response,
* error
* }: {
* data: FormData;
* form: HTMLFormElement;
* response: Response | null;
* error: Error | null;
* }) => void;
* result?: ({
* data,
* form,
* response
* }: {
* data: FormData;
* response: Response;
* form: HTMLFormElement;
* }) => void;
* }} [opts]
*/
export function enhance(form, { pending, error, result } = {}) {
let current_token;
/** @param {SubmitEvent} e */
async function handle_submit(e) {
const token = (current_token = {});
e.preventDefault();
const data = new FormData(form);
if (pending)
pending({ data, form });
try {
const response = await fetch(form.action, {
method: form.method,
headers: {
accept: 'application/json'
},
body: data
});
if (token !== current_token)
return;
if (response.ok) {
if (result)
result({ data, form, response });
const url = new URL(form.action);
url.search = url.hash = '';
invalidate(url.href);
}
else if (error) {
error({ data, form, error: null, response });
}
else {
console.error(await response.text());
}
}
catch (e) {
if (error && e instanceof Error) {
error({ data, form, error: e, response: null });
}
else {
throw e;
}
}
}
form.addEventListener('submit', handle_submit);
return {
destroy() {
form.removeEventListener('submit', handle_submit);
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment