Hello! Continuing this mini-series I'd like to share with you how I dealt with complex forms in Remix. You see, I'm creating this training plan builder, that currently looks like this
The Remix expects you to process data, sent to the backend, via actions
. It's pretty cool when you're dealing with simple forms, but here I have these columns and each column has multiple exercises, so it'd be great if I could group the data somehow.
The first idea was to deal with it as they have it in docs, so something like this
export const action = async ({ request }) => {
const formData = await request.formData();
const title = formData.get("title");
const slug = formData.get("slug");
const markdown = formData.get("markdown");
...
}
This way I would somehow call Object.entries
on formData while giving the input names like col-1-ex-1
. You can imagine how tedious that was/would be. So, I searched for a solution and I found a pretty clever one with the help of the qs
(querystring) package.
The package ensures I can give each of the exercise inputs names like
- phases[${idx}][${exercise.id}][title]
- phases[${idx}][${exercise.id}][sets]
- phases[${idx}][${exercise.id}][reps]
which, after parsing the request with this snippet
export const action: ActionFunction = async ({ request }) => {
const text = await request.text();
const parsed = qs.parse(text) as YourCustomType
...
}
gives the following structure
phases: [
{
exerciseId: {
sets: number,
reps: number,
title: string,
},
exerciseId2: {
sets: number,
reps: number,
title: string,
}
},
{
exerciseId3: {
sets: number,
reps: number,
title: string,
}
},
{
exerciseId4: {
sets: number,
reps: number,
title: string,
},
exerciseId5: {
sets: number,
reps: number,
title: string,
}
},
] // 3 objects represent 3 columns (phases) in the app
This structure is much easier to work with. And the best thing is that I got this structure using only two lines of code 😅
Thanks for reading and hope this helps someone! Take care 😉
Source code -> Strongion
Original thread -> github discussion
Top comments (0)