Description
Are there a possibility to bind post form values from array of objects using gin?
How to reproduce
I have post form like
<input type="text" name="class">
<!-- first student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
<!-- second student -->
<input type="text" name="students[][first]">
<input type="text" name="students[][last]">
<input type="text" name="students[][age]">
And go code
type Student struct {
First string `form:"first"`
Last string `form:"last"`
Age int `form:"age"`
}
type Class struct {
Class string `form:"class"`
Students []Student `form:"students[]"`
}
func Handle(c *gin.Context) {
err := c.Request.ParseForm()
if err != nil {
log.Fatal(err)
}
class:= new(Class)
err = c.Bind(class)
if err != nil {
log.Fatal(err)
}
log.Println(c.Request.PostForm)
log.Println(class)
}
I receive next output
map[students[][first]:[John Jack] students[][last]:[Johny Jacky] students[][age]:[20 30] class:[myclass]]
&{myclass []}
But I expect to receive array of structs Student and get output like
&{myclass [{John Johny 20} {Jack Jacky 30}]}
How is it possible to do it?
Environment
- go version: go version go1.12.7 linux/amd64
- gin version (or commit ref): v1.4.0
- operating system: Ubuntu 16.10
Similar issue https://github.com/gin-gonic/gin/issues/1523
Comment From: vkd
Unfortunately it is not possible yet.
Comment From: optimistic9527
same question,hope support
Comment From: shane-od
Can't wait to see this supported! Coming from PHP, things like this were very common.
Comment From: ChanJuiHuang
Please support this feature!
Comment From: fgm
For a concrete example, this is used by the Mailchimp API webhooks, over which we have no control.
Comment From: dungtranhoang
does this issue supported yet? Really need to handle this case!
Comment From: lylest
Subject: Simplifying MongoDB Array of Objects Update in Go with Gin
Hi there,
I recently faced a challenging task of updating an array of objects in my MongoDB document using Go with Gin. The document structure looked like this:
{
"permissions": [
{
"id": 0,
"name": "users",
"list": []
},
{
"id": 1,
"name": "customers",
"list": []
}
]
}
Finding a solution was a bit of a headache, and I tried several approaches. Eventually, I found a clean and effective solution. Here's how I did it:
Document Structure:
type PermissionsList struct {
PermissionList []Permission `json:"permissionList" bson:"permissionList"`
}
type Permission struct {
ID interface{} `json:"id" bson:"id"`
Name string `json:"name" bson:"name"`
List []string `json:"list" bson:"list"`
}
Decode JSON and Insert:
var permissions = new(models.PermissionsList)
decodeErr := utils.DecodeJSON(context, permissions)
if decodeErr != nil {
return decodeErr, "Failed to decode body", nil, 500
}
JSON Decoder Function:
func DecodeJSON(context *gin.Context, modelInterface interface{}) error {
err := context.BindJSON(&modelInterface)
if err != nil {
return err
}
return nil
}
Update MongoDB Document:
idErr, objectId := utils.ToObjectId(id)
if idErr != != nil {
return idErr, "Invalid user id", nil, 422
}
opts := options.FindOneAndUpdate().SetUpsert(true)
filter := bson.D{{"_id", objectId}}
update := bson.D{
{
"$set",
bson.D{
{"permissions", permissions.PermissionList},
},
},
}
This structure worked seamlessly for updating the MongoDB array of objects. Feel free to use it in your projects or adapt it to fit your specific needs.
Best regards,