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
Related
I am mocking a method call as follows:
tctx.someMock.On("addProd",
product.NewAddProductParamsWithContext(ctx).
WithID("someid").
WithCreateRequest(pro.CreateProdBody{
creationDate: "someDate" ,
}), nil).
Return(nil, nil)
which works fine.
Now, here, instead of passing a fixed value for the field creationDate, if I want to generalize it so it will work for any value passed, how can I achieve that? I am pretty new to Go, so not sure how to do this
the values for creationDate could be any value like - 2021-03-19T18:57:16.589Z or 2022-04-23T14:17:56.589Z etc. I just dont want to limit the mock call to work for a fixed value of creationDate, but I would like it to work for any date string passed
Assuming you're using github.com/stretchr/testify/mock, you should be able to use mock.MatchedBy() to match on specific parts of the argument. For example:
tctx.someMock.On("addProd", mock.MatchedBy(func(i interface{}) bool {
p := i.(*product.AddProductParams)
return p.ID() == "someid"
})).Return(nil, nil)
However, I find this to be most useful when needing to take a different action depending on the input. If you're simply verifying addProd was called with a specific argument, consider asserting that instead:
tctx.someMock.On("addProd", mock.Anything).Return(nil, nil)
...
tctx.someMock.AssertCalled(t, "addProd", mock.MatchedBy(func(i interface{}) bool {
p := i.(*product.AddProductParams)
return p.ID() == "someid"
})).Return(nil, nil)
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
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.