Lesson 10 Lab — The Categories Create/Edit Form¶
Finish Categories CRUD with its form — the simplest form in the app: no FK dropdown, just
two fields. You've built two shared create/edit forms already: the Menu Item form (guide,
with a Category FK dropdown) and the Staff form (lab, no FK). This one is closest to
Staff — build it from memory, using StaffForm as your model.
Prerequisite: your API is running on the HTTP profile (
http, nothttps) with Categories seed data, and you have the Categories list from the Lesson 9 lab.
The form fields¶
Name (required) and Sort Order (required, valueAsNumber). That's it — no FK, no
dropdown.
Steps¶
Same arc as the Staff form: API calls → the shared form → thin pages + routes.
- Add
post(category)andput(category)toCategoryAPI.ts— the last two methods (your module already haslistfrom Lesson 7,findfrom the Lesson 8 lab, anddeletefrom the Lesson 9 lab). CategoryForm—useForm<ICategory>; read:idwithuseParams; asyncdefaultValuesreturns anemptyCategory(no:id) orcategoryAPI.find(Number(id)). Register Name (required) and Sort Order (required,valueAsNumber), each with theis-invalid+invalid-feedbackdisplay.save: POST when!category.idelse PUT, thennavigate("/categories").- Thin
CategoryCreatePage/CategoryEditPage(heading +<CategoryForm />) and routescategories/createandcategories/edit/:idunderLayout. - ✅ Checkpoint: Add Category opens an empty form; Save-empty shows inline errors; a valid save returns to the list (201); ⋮ → Edit pre-fills the form and saves (200).
Verify in the browser¶
With your API running and npm run dev up:
- Add Category →
/categories/create: empty form. Save with Name empty → red field + "Name is required" (no request). Fill both fields, Save → back to the list, new card, 201POST. - ⋮ → Edit a card → fields pre-filled; change the sort order, Save → 200
PUT, card updates. - Confirm create and edit are the same form — only the URL's
:iddiffers. Console clean.
That completes Categories CRUD — list, card, form — the same shared-form pattern a third time, on the simplest entity. On PRS this is the Vendors form (also no FK).
Stretch challenges¶
Optional — for when you finish early. Not needed for the capstone. [Reinforce] builds on what you've done; [Reach] goes past it and needs some research.
maxLengthrule — [Reinforce] — add amaxLengthrule (not the native attribute) to Name and paste a long string to watch the message fire — the paste-bypass demo from the Lesson 7 guide, on your own form.- Disable Save while submitting — [Reinforce] — pull
formState.isSubmittingand setdisabled={isSubmitting}on the Save button so a slow POST can't be double-submitted. - Sensible default sort order — [Reach] — default a new category's
sortOrderto one past the current max (fetch the list,Math.max(...sortOrders) + 1) so new categories land at the end. Research react-hook-form default values: useForm defaultValues.
Finished these and want more? See stretch-react-challenges.md for bigger challenges that span the whole React pass.