I separated my HTML into two files, +page.svelte and Role.svelte. This is so it's cleaner and more maintainable as I will add more svelte files into +page.svelte in the future. Role.svelte contains the form.
I've read that since form is only passed to +page.svelte and not to any components, instead of using let form: ActionData in Role.svelte I should just use $page.form by itself on Role.svelte. An issue I'm encountering is $page.form doesn't have type safety and type inference unlike ActionData. How can I make $page.form have the same inference as let form: ActionData without sacrificing the file organization?
(Here is the code):
Role.svelte
<script lang="ts">
import { enhance } from "$app/forms";
import { page } from "$app/stores";
import type { ActionData } from "./$types";
let form: ActionData = $page.form // tried, returned undefined
form = form // did not change anything
let userRoles = ["admin", "student"];
</script>
<form method="post" action="?/role" use:enhance>
<!-- did not work, had to use $page.form which again has no typing -->
{#if form?.noSelectedRole}
<p>{form?.error}</p>
{/if}
<p>You are a/an...</p>
{#each userRoles as userRole}
<input type="radio" value={userRole} name="role" />
<label for={userRole}>{userRole}</label>
<br />
{/each}
<slot />
<!-- For when the school can't be found -->
<p>What school are you a part of? Type its DepEd school ID.</p>
<input type="text" name="schoolId" placeholder="School" />
<br />
<button type="submit">Check</button>
</form>
+page.svelte
<script lang="ts">
import { page } from "$app/stores";
import type { ActionData } from "./$types";
import Role from "./Role.svelte";
let form: ActionData = $page.form // did not work
</script>
<Role>
<p>
<!-- undefined, had to use $page.form but again, no typing :( -->
{console.log(form?.noSelectedRole)}
{#if form?.noSelectedRole}
Select a role please.
{/if}
</p>
</Role>
+page.server.ts
import type { Actions } from "./$types";
import { fail, redirect } from '@sveltejs/kit';
export const actions = {
role: async ({ request }) => {
const formData = await request.formData()
const userRole = formData.get("role") as string
const schoolId = formData.get("schoolId") as string
console.log(`role: ${userRole}`)
console.log(`school id: ${schoolId}`)
if (typeof userRole !== "string" ||
userRole == null) {
console.log("no user role selected")
return fail(400, {
noSelectedRole: true,
error: "Please select a role.",
data: {...{userRole, schoolId}}
})
}
}
} satisfies Actions;