We have the following ajaxParams:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint',
dataType: 'json',
customParam: 'customParam',
success: onResponse,
error: onError,
};
Is it possible for Golang to read the custom attribute as it appears in the form of an *http.Request object in the associated Golang handler?
Those parameters are used to do the AJAX request, they are not what actually gets to the server. You should pass it as the data of the POST request, as in:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint',
dataType: 'json',
data: {customParam: 'customParam'},
success: onResponse,
error: onError,
};
$.ajax(ajaxParams);
Then, on the Go side, you just handle the data as you want it, like in:
type MyStruct {
customParam string `json:"customParam"`
}
func HandlePost(w http.ResponseWriter, r *http.Request) {
dec := json.NewDecoder(r.Body)
var ms MyStruct
err := dec.Decode(&ms)
if err != nil {
panic(err)
}
fmt.Println(ms.customParam)
}
Assuming you want your param to be a string. Either way you could convert it to the type you want.
Related
We have the following AJAX call to a golang endpoint:
var ajaxParams = {
type: 'POST',
url: '/golang_endpoint'
dataType: 'json',
processData: false,
timeout: timeout,
contentType: 'application/json',
data: JSON.stringify({"test": 1, "test2": "val"}),
};
$.ajax(ajaxParams);
However, req.PostForm looks like it was parsed incorrectly:
req.ParseForm()
fmt.Println(req.PostForm)
We get: map[{"test":1,"test2":"val"}:[]]
Why did ParseForm end up getting parsed this way? How can we parse it so that PostForm is of value map[test: [1] test2: [val]]
EDIT:
This is a potential solution:
var ajaxParams = {
contentType: 'application/json',
data: JSON.stringify({"test": 1, "test2": "val"}),
...
};
data, err := ioutil.ReadAll(req.Body)
var m map[string]interface{}
err = json.Unmarshal(data, &m)
fmt.Println(m)
I want to get all the post form data and get the values as string, however using PostParams I am able to get all the post data, but the values are as array key: [value], how can I get all the form data as string values?
[Edit]
I may not stated clearly, but I need to get the whole form as JSON, because I need to send the form data to another API which need the body as JSON data
form.html
<form>
<input type='text' name='key' />
<input type='text' name='key2' />
</form>
script.js
$.ajax( {
url: '/post/action',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false
}).done(function(r) {
console.log(r);
});
action.go
func PostAction(c echo.Context) error {
form, _ := c.FormParams()
b, _ := json.Marshal(form)
log.Println(b) // this will print: key: [value], key2: [value]
// I want to get value as string: key: value, key2: value
// ..other function, return, etc
}
How can I get the form values as string?
Or is there another function that does this?
Thank you very much in advance
No need to JSON marshal the already decoded form, simply do:
form["key"][0]
form["key2"][0]
See the docs on c.FormParams and then click on the return type to see its documentation, and you'll notice that it's just the stdlib's url.Values type, which is defined as a map of string slices (i.e., map[string][]string).
If you need to convert a value of type url.Values to a "simple object", you can convert it to a map[string]string using the following code:
o := make(map[string]string, len(form))
for k, v := range form {
// if you are certain v[0] is present
o[k] = v[0]
// if you are not sure v[0] is present, check first
if len(v) > 0 {
o[k] = v[0]
}
}
data, err := json.Marshal(o)
if err != nil {
return err
}
// ...
I have the following function where I want to send arbitrary JSON data to a websocket connection. The data depends on what was sent to the server. How this can be achieved without creating different structs for each thing I want to send?
I am thinking about something like this:
func Register(c *websocket.Conn, m WebsocketGeneralClientMessage) {
var d RegisterData
json.Unmarshal(m.Data, &d)
if len(d.Email) < 6 || len(d.Email) > 64 {
c.WriteJSON(WebsocketGeneralServerMessage{
Type: "error", Data: map[string]interface{"text": "This is an error"}})
return
}
if len(d.Password) < 6 || len(d.Password) > 32 {
c.WriteJSON(WebsocketGeneralServerMessage{
Type: "error", Data: map[string]interface{"text": "This is another error"}})
return
}
err := checkmail.ValidateFormat(d.Email)
if err != nil {
c.WriteJSON(WebsocketGeneralServerMessage{
Type: "error", Data: map[string]interface{"text": "This is different than all the previous errors"}})
return
}
uuid, email, password, err := DB.RegisterAccount(requestEmail, requestPassword)
if err != nil {
c.WriteJSON(WebsocketGeneralServerMessage{
Type: "error", Data: map[string]interface{"text": "An error occured while saving the account to the database"}})
return
}
c.WriteJSON(WebsocketGeneralServerMessage{
Type: "success", Data: map[string]interface{"uuid": uuid}})
return
}
type WebsocketGeneralServerMessage struct {
Type string
Data map[string]interface{}
}
However, the compiler says:
syntax error: unexpected literal "text", expecting method or interface name
so it seems this syntax is not valid. What can be done here?
It's map[string]interface{}{"text": .... You missed the {}.
My problem is similar to that of the question in this link. I need to return multiple slices or a struct from golang to the ajax success block. I tried to marshal my slice into JSON but it is received in ajax as a string. I need to receive it as an array. Is it possible to send multiple arrays or a struct like this?
My code:
b, _ := json.Marshal(aSlice) // json Marshal
c, _ := json.Marshal(bSlice)
this.Ctx.ResponseWriter.Write(b) // Beego responsewriter
this.Ctx.ResponseWriter.Write(c)
My ajax:
$.ajax({
url: '/delete_process',
type: 'post',
dataType: 'html',
data : "&processName=" + processName,
success : function(data) {
alert(data);
alert(data.length)
}
});
Thanks in advance.
The dataType parameter of your ajax request should be json as you are expecting JSON data from the server. But if you server does not respond with valid JSON the ajax request is going to result in an error. Check your browser's javascript console for errors.
From what you are currently doing in the controller, its definitely going to result in invalid JSON response. See following.
aSlice := []string{"foo", "bar"}
bSlice := []string{"baz", "qux"}
b, _ := json.Marshal(aSlice) // json Marshal
c, _ := json.Marshal(bSlice)
this.Ctx.ResponseWriter.Write(b) // Writes `["foo","bar"]`
this.Ctx.ResponseWriter.Write(c) // Appends `["baz","qux"]`
This results in sending ["foo","bar"]["baz","qux"] Thats just two JSON array strings appended together. Its not valid.
What you probably want to send to browser is this: [["foo","bar"],["baz","qux"]].
That is an array of two arrays. You can do this to send it from the server.
aSlice := []string{"foo", "bar"}
bSlice := []string{"baz", "qux"}
slice := []interface{}{aSlice, bSlice}
s, _ := json.Marshal(slice)
this.Ctx.ResponseWriter.Write(s)
And in the javascript side,
$.ajax({
url: '/delete_process',
type: 'post',
dataType: 'json',
data : "&processName=" + processName,
success : function(data) {
alert(data);
alert(data[0]); // ["foo","bar"]
alert(data[1]); // ["baz","qux"]
alert(data.length) // 2
}
});
The answer of #AH works really well for multiple slices. Now if you want a Struct you should change a little bit your code :
package controllers
import "github.com/astaxie/beego"
import "encoding/json"
type Controller2 struct {
beego.Controller
}
type Controller2Result struct {
Accommodation []string
Vehicle []string
}
func (this *Controller2) Post() {
var result Controller2Result
aSlice := []string{"House", "Apartment", "Hostel"}
bSlice := []string{"Car", "Moto", "Airplane"}
result.Accommodation = aSlice
result.Vehicle = bSlice
s, _ := json.Marshal(result)
this.Ctx.ResponseWriter.Header().Set("Content-Type", "application/json")
this.Ctx.ResponseWriter.Write(s)
}
Ajax
$.ajax({
url: '/Controller2',
type: 'post',
dataType: 'json',
//data : "&processName=" + processName,
success : function(data) {
alert(JSON.stringify(data));
}
});
How is explained here alert only can display strings and datais a object type of JavaScript. So you have to use JSON.stringify to turn object into JSON-String.
I have a URL that looks something like this: http://localhost/templates/verify?key=ijio
My router looks like this:
import (
"github.com/gorilla/mux"
"github.com/justinas/alice"
)
ctx := &model.AppContext{db, cfg} // passes in database and config
verifyUser := controller.Verify(ctx)
mx.Handle("/verify", commonHandlers.ThenFunc(verifyUser)).Methods("GET").Name("verify")
I want to get the key parameter out of the URL, so I use the following code:
func Verify(c *model.AppContext) http.HandlerFunc {
fn := func(w http.ResponseWriter, r *http.Request) {
key := r.URL.Query().Get("key") // gets the hash value that was placed in the URL
log.Println(key) // empty key
log.Println(r.URL.Query()) // returns map[]
// code that does something with key and sends back JSON response
}
}
I used AngularJS to get the JSON data:
app.controller("verifyControl", ['$scope', '$http', function($scope, $http) {
$scope.message = "";
$http({
method: 'GET',
url: "/verify"
}).success(function(data) {
$scope.message = data.msg; // JSON response
});
}]);
However, I end up with an empty key variable when I try to print it out. I recently used nginx to take out my .html extension if that's a possible cause of this problem. How do I fix this?
The solution to my question involves inspecting the request URL link by
log.Print(r.URL) // This returns "/verify"
However, that's not exactly what you want. Instead, you want the full URL. You can do the following to get the full URL and extract the parameter from it:
urlStr := r.Referer() // gets the full URL as a string
urlFull, err := url.Parse(urlStr) // returns a *URL object
if err != nil {
log.Fatal(err)
return
}
key := urlFull.Query().Get("key") // now we get the key parameter from the URL
log.Println("Key: " + key) // now you'll get a non empty string