DEV Community

Andrej Tlčina
Andrej Tlčina

Posted on • Updated on

Building Training Plan builder: Dealing w/ complex forms in Remix

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

Image description

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");
  ...
}
Enter fullscreen mode Exit fullscreen mode

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

  ...
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)