Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🤗 [Question]: How do we get multiple values for a key in form submission? #3159

Open
3 tasks done
ngocchien opened this issue Oct 8, 2024 · 3 comments
Open
3 tasks done

Comments

@ngocchien
Copy link

ngocchien commented Oct 8, 2024

Question Description

I have a field in my form, its name is the description

Example:

<input name="item" value="item1">
<input name="description" value="description1, this is a description for item one, the first item is very nice, bla bla bla">
<input name="item" value="item2">
<input name="description" value="description2">
<input name="item" value="item3">
<input name="description" value="description3">

On my server side, I define a struct with the information:

FormCreate struct {
		Item    []string                   `json:"item" form:"item"`
		Description  []string         `json:"description" form:"description"`
	}
formData = new(FormCreate)
c.Bind().Body(formData)

I have a problem with binding data from the form to my formData.
My expectation data for formData.Description is []string{"description, this is a description for item one, the first item is very nice, bla bla bla", "description2", "description3"} (This has 3 values for the slice).
But currently, I received for formData.Description after binding data is []string{"description1", "this is a description for item one", "the first item is very nice", "bla bla bla", "description2", "description3"} (This has 6 values for the slice).

It seems that the Bind() function has split the value of the description field of the first item into a slice by the "," , so I received the data for formData.Description is []string{"description1", "this is a description for item one", "the first item is very nice", "bla bla bla", "description2", "description3"}.

Who can resolve my problem?
Thank you so much!

Code Snippet (optional)

package main

import "github.com/gofiber/fiber/v3"
import "log"

func main() {
  app := fiber.New()

  // An example to describe the question
  app.Post("/create-post", handleCreate) 
  log.Fatal(app.Listen(":3000"))
}

function handleCreate(c fiber.Ctx) error{
   FormCreate struct {
		Item    []string                   `json:"item" form:"item"`
		Description  []string         `json:"description" form:"description"`
	}
  var (
    formData = new(FormCreate)
  )
   if c.Method() == http.MethodPost {
	err = c.Bind().Body(formData)
   }
   
   return c.Render("index", fiber.Map{
        "formData": formData,
    })
}

Checklist:

  • I agree to follow Fiber's Code of Conduct.
  • I have checked for existing issues that describe my questions prior to opening this one.
  • I understand that improperly formatted questions may be closed without explanation.
Copy link

welcome bot commented Oct 8, 2024

Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@michal-laskowski
Copy link

@gaby

Look at this regarding to #3203

@michal-laskowski
Copy link

For JSON it will work

JSON test
// go test -v -run=^$ -bench=Test_Bind_Body_JSON_WithArray
func Test_Bind_Body_JSON_WithArray(b *testing.T) {
	var err error

	app := New()
	c := app.AcquireCtx(&fasthttp.RequestCtx{})

	type Demo struct {
		Item        []string `json:"item" form:"item"`
		Description []string `json:"description" form:"description"`
	}
	body := []byte(`{"item":["item1","item2","item3" ], "description":["description1, with coma.","description2","description3" ] }`)
	c.Request().SetBody(body)
	c.Request().Header.SetContentType(MIMEApplicationJSON)
	c.Request().Header.SetContentLength(len(body))
	d := new(Demo)

	err = c.Bind().Body(d)
	require.NoError(b, err)
	require.Equal(b, []string{"item1", "item2", "item3"}, d.Item)
	require.Equal(b, []string{"description1, with coma.", "description2", "description3"}, d.Description)
}

For forms it will not work if you allow comma (,) in value.

Form test
// go test -v -run=^$ -bench=Test_Bind_Body_Form_WithArray
func Test_Bind_Body_Form_WithArray(b *testing.T) {
	var err error

	app := New()
	c := app.AcquireCtx(&fasthttp.RequestCtx{})
	type Demo struct {
		Item        []string `json:"item" form:"item"`
		Description []string `json:"description" form:"description"`
	}

	body := []byte("item=item1&item=item2&item=item3&description=description1%2C%20with coma.&description=description2&description=description3&q=%2C")
	c.Request().SetBody(body)
	c.Request().Header.SetContentType(MIMEApplicationForm)
	c.Request().Header.SetContentLength(len(body))
	d := new(Demo)

	err = c.Bind().Body(d)

	require.NoError(b, err)
	require.Equal(b, []string{"item1", "item2", "item3"}, d.Item)
	require.Equal(b, []string{"description1, with coma.", "description2", "description3"}, d.Description)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants