I'm in a situation where I want to get an unknown number of input values into my Go structs, but only some of them will be placed inside a slice/array. Here's a snippet of the HTML content:
<form action="/" method="post">
...
<tbody>
{{ range .users }}
<tr>
<td class="text-center">
<img class="avatar" src="{{ .AvatarThumbnailURL }}">
<input type="hidden" name="thumbnail" value="{{ .AvatarThumbnailURL }}">
</td>
<td>
{{ .Username }}<input type="hidden" name="username" value="{{ .Username }}">
</td>
<td>
{{ .Age }}<input type="hidden" name="age" value="{{ .Age }}">
</td>
<td>
{{ .Email }}<input type="hidden" name="email" value="{{ .Email }}">
</td>
</tr>
<input type="hidden" name="userid" value="{{ .UserID }}">
{{end}}
</tbody>
...
{{ .csrfField }}
// submit button
</form>
Where {{ .csrfField }}
will generate a hidden input. This part is working fine.
Now the problem is how do I get this data inside a struct?
Let's say I have the following struct:
type UserFormData struct {
UserID int
Username string
AvatarThumbnailURL string
Age int
Email string
}
But in my POST function I don't know how many users will be submitted through the form. So I guess I have to do something like this:
userFormData := make([]UserFormData, len(r.PostForm)/6)
(divided by 6 because there are AvatarThumbnailURL, Username, Age, Email, UserID and csrfField)
Then can go through the r.PostForm like this:
i := 0
j := 0
for key, values := range r.PostForm {
switch key {
case "userid":
userid, _ := strconv.Atoi(values[0])
userFormData[j].UserID = userid
case "thumbnail":
userFormData[j].Thumbnail = values[0]
// the other fields
i++
if i%6 == 0 {
j++
}
}
While this work, it's extremely error prone to indexoutofrange and whenever I make a change then I have to count number of input values that will be sent with the form and update the (currently) '6' values. I have no doubt that there must be a much, much, much better way to do this, and I would greatly appreciate if someone could point me in the right direction :)