gin icon indicating copy to clipboard operation
gin copied to clipboard

Binding array of objects from post form

Open Ragnar-BY opened this issue 5 years ago • 7 comments

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

Ragnar-BY avatar Dec 10 '19 15:12 Ragnar-BY

Unfortunately it is not possible yet.

vkd avatar Dec 12 '19 06:12 vkd

same question,hope support

optimistic9527 avatar Mar 16 '20 06:03 optimistic9527

Can't wait to see this supported! Coming from PHP, things like this were very common.

shane-od avatar Aug 07 '20 14:08 shane-od

Please support this feature!

chan-jui-huang avatar Nov 07 '22 12:11 chan-jui-huang

For a concrete example, this is used by the Mailchimp API webhooks, over which we have no control.

fgm avatar Feb 26 '23 19:02 fgm

does this issue supported yet? Really need to handle this case!

dungtranhoang avatar May 17 '23 10:05 dungtranhoang

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,

lylest avatar Jan 05 '24 09:01 lylest