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,