Is there an easy way to list / iterate through all post values using Gin Gonic? (Go)
I have tried:
c.Request.ParseForm()
for key, value := range c.Request.PostForm {
log.Printf("POST %v = %v",key,value)
}
But this shows no values, however when I test the values directly from context:
log.Printf("POST email = %v", c.PostForm("email")
It outputs fine.
What I'm trying to do is to map all post values into a gin.H{} context, so that upon failure I can pass the posted values back into the .HTML template context and have them prefilled (along with my error message). Best I've found is manually wiring each POST value to the gin.H{} map, but for a large form these seems verbose and not ideal.
We also needed something like #BadPirate describes so if anyone need for gin 1.6.2
func register(c *gin.Context){
c.MultipartForm()
for key, value := range c.Request.PostForm {
log.Printf("%v = %v \n",key,value)
}
}
Thanks #BadPirate and #phoet for the info.
Issue here was the form (not shown) was a multipart form. ParseForm does not parse multipart forms, and thus, no data. The fix is to call ParseMultipartForm instead. Thanks to #phoet for pointing at the method in Gin Gonic for PostForm (which calls ParseMultipartForm for you, and does so automatically), which helped lead me to the answer.
Related
In go-fiber docs they say:
As a rule of thumb, you must only use context values within the
handler, and you must not keep any references
is it OK if I passing around the context as a function argument like this:
func GetList(c *fiber.Ctx) error {
result, err := User.Search(c)
}
func Search(c *fiber.Ctx) (User, err) {
id := c.Params("id")
}
is that considered as a bad practice?
And I don't really understand this sentence:
As soon as you return from the handler, any values you have obtained
from the context will be re-used in future requests and will change
below your feet.
So if I have sent the response to the client the value of params will be reused? reused by whom? by me or by other people's request?
func GetList(c *fiber.Ctx) error {
id := c.Params("id") // 911
return c.SendString("Hello, World!")
}
so if the value of id was 911 does that mean other people request will also result in 911?
and what's the meaning of
will change below your feet
can anyone elaborate more easy for beginner like me to understand? thanks...
The actual context object can be reused by the framework after it calls your handler, so you cannot rely on its state after you return from the handler.
is it OK if I passing around the context as a function argument like this?
This is fine, as long as Search doesn't store the context elsewhere. If it just uses values from the context to conduct a search and then returns a result, that's fine.
So if I have sent the response to the client the value of params will be reused? reused by whom? by me or by other people's request?
The actual context object will be reused by the framework, while handling a later request.
and what's the meaning of "will change below your feet"?
If you don't follow the advice above, and instead keep references to the context after returning from your handler, the values in that context will change unexpectedly, since the framework is using that context for a new request.
everybody!
The question is:
How to write multiple parameters in query router, so I can write one, two or more parameters like this:
/applications/filter/?date=today
/applications/filter/?status=true
/applications/filter/?date=today&status=true
I tried this, but it does not work for single parameter, only for two:
router.HandleFunc("/applications/filter/", authMiddle.RequiresLogin(authContrl.FilterDateStatus())).
Queries("date", "{date}", "status", "{status}").Methods("GET")
This is a little bit confusing in the beginning, but your route is always the same here:
/applications/filter/?date=today
/applications/filter/?status=true
/applications/filter/?date=today&status=true
It is always /applications/filter/.
In that case you just need to map one route here. The handle func receives the request. Inside the request you can parse the url.
https://play.golang.org/p/op49nTJSlCP
Putting all together it could look like:
router.HandleFunc("/applications/filter/",func(w http.ResponseWriter,r *http.Request){
// in production you should handle the errors!
// I am just skipping this to keep the example simple
u, _ := url.Parse(r.URL)
v := u.Query()
if _,ok := v[date]; ok {
// do something with dae
}
})
As the title says , is there an api for that?
*fasthttp.Request.Header.key
When I call the method with POSTMAN , I can't get the header content key as the above code . Why
It may surprise you to learn that fasthttp doesn't store request header values as an exported map[string]string, but as an unexported []byte which it stores indexes into. This apparently is one of its performance optimizations.
You can get a request header value with Peek().
v := ctx.Request.Header.Peek("User-Agent")
Note that this function returns a byte slice, so you'll probably have to convert it to a string.
sv := string(v)
My question is about appending to a map which is a filed/key of an interface. This is required to build a JSON object. I am using map[string]interface{} to be able to append any struct types to it. I am not sure if that is a right way as I am still learning Go but I could not find a better way. Below is a link to a playground:
https://play.golang.org/p/cxpSep8OQD.
I think I need to use type accretion but I do not understand how. Any help would be useful.
If all you have are Group values, then declare outJson as a map of *Group:
outJson := make(map[string]*Group, len(groups))
Playground Example
If the map can contain different value types, then use a type assertion to access the group:
g, ok := outJson["a"].(*Group)
if !ok {
panic("handle error a better way")
}
g.Hosts = append(g.Hosts, "hostname")
Playground Example
I have rest API defined as
apis.GET(/home, validatationHandler , dashboardHandler)
I want pass some data from validatationHandler to dashboardHandler. For this I thought of using header. To set the data I use this in validatationHandler
c.Writer.Header().Set("myheader", "mytoken")
c.Next()
and in dashboardHandler I tried to access it using
fmt.Println(c.Request.Header.Get("myheader"))
But the value is always nil. Any idea how can I set and retrieve headers? Is there any other way I can pass on the data from 1 handler to another?
You can pass values via gin.Context
Use ctx.Set(k, v) in fisrt one and ctx.Get(k) in the next.
So How to Use It:
ctx.Set("myKey", 100)
and get it using
v, ok := ctx.Get("myKey")
if ok {
actualValue := v.(int) // you need to type convert it as it returns interface.
}
See context.go