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: chan-jui-huang

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,

Comment From: rfx77

You can use this library. https://github.com/go-playground/form

It has all features to parse form values into structs, including arrays.