I have a Form html like :
<input name="email"type="email" />
<input name="password"type="password" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="freeword[]"type="text" />
<input name="freeword[]"type="text" />
I want to Bind()
this form with my struct
like :
type UserFrom struct {
Email string `json:"email" form:"email" query:"email"`
Password string `json:"password" form:"password" query:"password"`
Tags []Tag
Free []string `json:"freeword[]" form:"freeword[]" query:"freeword[]"`
}
type Tag struct {
Name string `json:"tags[name][]" form:"tags[name][]" query:"tags[name][]"`
Count string `json:"tags[count][]" form:"tags[count][]" query:"tags[count][]"`
}
But if i print the result of Bind()
after POST
i have :
u := new(UserFrom)
if err = c.Bind(u); err != nil {
return
}
log.Println(u)
This bad Output :
&{email@mail.tld pwdpwdpwd [] [word1 word2]}
The row Tags []Tag
in UserFrom
struct does not work
If y try to change Tags []Tag
to Tags Tag
i have a good last entry
&{email@mail.tld pwdpwdpwd {tag3 3} [word1 word2]}
I want this output :
&{email@mail.tld pwdpwdpwd [{tag1 1} {tag2 2} {tag3 3}] [word1 word2]}
do you have an idea of the problem ?
Thx @alexaandru for your reply,
I have update form fields to :
<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />
<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />
<input name="tags[][name]"type="text" />
<input name="tags[][count]"type="number" />
And i have create a simple for
u := new(UserForm)
if err := c.Bind(u); err != nil {
}
fiels, _ := c.FormParams()
var tags []Tag
var tag Tag
for i := 0; i < len(fiels["tags[]tag"]); i++ {
count, _ := strconv.Atoi(fiels["tags[][count]"][i])
tag.Name = fiels["tags[][name]"][i]
tag.Comment = count
tags = append(tags, tag)
}
u.Tags = tags
log.Println(u)
I have nice output :
&{email@mail.tld pwdpwdpwd [{tagX 1} {tagY 2} {tagZ 3}] [wordX wordY]}
There are two problems:
tags[][name]
in order to achieve what you want, see here for example: HTML Form: POST an array of objectshttp.Request.Form
to parse the values, which is effectively url.Values
which in turn is just a map[string][]string
. As you can see, that cannot possibly capture the structure you want. Here is a relevant ticket: https://github.com/golang/go/issues/29703Now, just because Echo does not support that out of the box, it doesn't mean you cannot do it. You can use a 3rd party library for binding that has the features you need, such as https://github.com/monoculum/formam
The following code:
package main
import (
"fmt"
"net/url"
"github.com/monoculum/formam"
)
type User struct {
Email,
Password string
Tags []struct {
Tag string
Count int
}
}
func main() {
formData := "Email=joe@example.com&Password=secret&Tags[0].Tag=red&" +
"Tags[0].Count=1&Tags[1].Tag=blue"
q, _ := url.ParseQuery(formData)
u := new(User)
dec := formam.NewDecoder(nil)
if err := dec.Decode(q, u); err != nil {
fmt.Println(err)
return
}
fmt.Println(u)
}
results in what you need:
&{joe@example.com secret [{red 1} {blue 0}]}
Hope this helps!