Array of model problem
Closed this issue · 15 comments
First of all, I hope to make myself understood.
Sometimes when I try to bind the form, the values are incomplete, sometimes I just receive 1 user, other times I receive 2 users, but with empty fields like:
USERS-----------------------> 2
User 1 FN-----------------------> FirstName1
User 1 LN-----------------------> LastName1
User 1 EA-----------------------> Email1@test.com
User 2 FN-----------------------> FirstName2
User 2 LN-----------------------> LastName2
User 2 EA----------------------->
I'm not really sure why this is happening. Thanks in advance.
I have this model:
type User struct {
FirstName string `form:"FirstName"`
LastName string `form:"LastName"`
Email string `form:"Email"`
}
type Users []User
My HTML Form (or something like that):
<form method="POST">
<input type="text" name="User[0].FirstName" value="FirstName1">
<input type="text" name="User[0].LastName" value="LastName1">
<input type="text" name="User[0].Email" value="Email1@test.com">
<input type="text" name="User[1].FirstName" value="FirstName2">
<input type="text" name="User[1].LastName" value="LastName2">
<input type="text" name="User[1].Email" value="Email2@test.com">
<input type="submit">
</form>
My Handler
func MyHandler(w http.ResponseWriter, req *http.Request) error {
decoder = formam.NewDecoder(&formam.DecoderOptions{
TagName: "form",
IgnoreUnknownKeys: true,
})
if err := req.ParseForm(); err != nil {
return err
}
u := &models.Users{}
if err := decoder.Decode(req.Form, u); err != nil {
return err
}
}
It is strange... I can't reproduce it...
func TestArray(t *testing.T) {
func TestArray(t *testing.T) {
type User struct {
FirstName string `form:"FirstName"`
LastName string `form:"LastName"`
Email string `form:"Email"`
}
c := struct {
Users []User
}{}
vals := url.Values{
"Users[0].FirstName": []string{"FirstName1"},
"Users[0].LastName": []string{"LastName1"},
"Users[0].Email": []string{"Email1@test.com"},
"Users[1].FirstName": []string{"FirstName2"},
"Users[1].LastName": []string{"LastName2"},
"Users[1].Email": []string{"Email2@test.com"},
}
dec := NewDecoder(&DecoderOptions{})
err := dec.Decode(vals, &c)
if err != nil {
t.Error(err)
}
t.Log("c ->", c)
}
I have a question: I see that you use "User[0]", so User points to a struct with a field named 'User' and it is an array of User type?
No...
I'm using the model "users" which is an array of the struct named User, so I expect something like:
Users {
{
"FirstName": "FirstName1"
"LastName": "LastName1"
"Email": "Email1@test.com"
},
{
"FirstName": "FirstName2"
"LastName": "LastName2"
"Email": "Email2@test.com"
},
}
Maybe i'm using wrong the form?
Yes, you are using it wrong. "User[0]" means for forman "searchs by a field named 'User' in the struct that I pass you".
If you want pass a array to decode then in the html form change "User[index_here]" to "[index_here]". I means, remove "User" in the beginning.
Okay, I'll try and see. Thanks
include code (go and html) to reproduce it because by test I cannot reproduce it
A question: Are you sure that the request from browser always send all data?
Yes... I know is strange, the browser sends the data and the server receives the form's values but when I try to parse it, some data goes missing. Also, I'm using Buffalo, and they have a method called "Bind" which uses formam so I'm not sure how to share the code with you.
I'm uploading 3 screens for you to see. I hope these can help.
if you can't see well the third image, this is a transcribed version:
INFO[2019-11-27T14:35:40Z] /daniels-company/users/ admin_id=11cfe6b5-514e-4a4b-92b6-92cf48bde69e content_type=application/x-www-form-urlencoded db=23.167117ms duration=393.943262ms form="{\"[0].Email\":[\"Email1@test.com\"],\"[0].FirstName\":[\"FirstName1\"],\"[0].LastName\":[\"LastName1\"],\"[1].Email\":[\"Email2@test.com\"],\"[1].FirstName\":[\"FirstName2\"],\"[1].LastName\":[\"LastName2\"],\"authenticity_token\":[\"lH9Iio/8prdUZOq5SCgn9qIUy7zEYcZFSCNNoOcwcLwPMKsmUlY5rTHMxRGTJy+3lUY7msQ6n7YCg7Y+A4NzRw==\"]}" human_size="0 B" method=POST params="{\"[0].Email\":[\"Email1@test.com\"],\"[0].FirstName\":[\"FirstName1\"],\"[0].LastName\":[\"LastName1\"],\"[1].Email\":[\"Email2@test.com\"],\"[1].FirstName\":[\"FirstName2\"],\"[1].LastName\":[\"LastName2\"],\"authenticity_token\":[\"lH9Iio/8prdUZOq5SCgn9qIUy7zEYcZFSCNNoOcwcLwPMKsmUlY5rTHMxRGTJy+3lUY7msQ6n7YCg7Y+A4NzRw==\"],\"slug_name\":[\"daniels-company\"]}" path=/daniels-company/users/ request_id=2be758ccfc54e52d4f28-4dfd0f5e92f820cd560f size=0 status=302
ok, I found the error. The form data includes "authenticity_token". Right now, the test fails. When I get home, I hope to fix it.
thanks you.
No... Thanks to you.
Sorry for my delay. For the moment, you can include "authenticity_token" to your struct and you should be ok. This weekend I hope fix it.
type FormUsers struct {
Token string `form:"authenticity_token"`
Users Users
}
I added a branch with a failing test case; see the message above.
I took a brief look at fixing it, but no obvious solution.
@arp242 thanks you! I haven't had time to fix it. I expect look it again this weekend and to see that we are can to do. thanks again.
sorry for the delay. This has been fixed with the latest commit.