I'm relatively new to Go, I'm struggling to get my head around using POST data with structs. What I essentially want to do is submit a form, then submit that form to MongoDB (haven't got that far yet). I can't work out how to use this form data with a struct.
package main
import "net/http"
type Paste struct {
Title string
Content string
Language string
Expires int
Created int64
}
func index(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
r.ParseForm()
// r.Form = map[title:[Wadup] content:[Brother]]
}
}
func main() {
http.HandleFunc("/", index)
http.ListenAndServe(":1234", nil)
}
What I basically want to do is insert the map values into the struct, without manually assigning all of them, like you can see here: p := Paste{Title: r.Form["title"]}
Use gorilla/schema, which was built for this use-case:
package main
import(
"net/http"
"github.com/gorilla/schema"
)
type Paste struct {
Title string
Content string
Language string
Expires int
Created int64
}
var decoder = schema.NewDecoder()
func index(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
// handle error
var paste = &Paste{}
err := decoder.Decode(paste, r.PostForm)
// handle error
}
After you called r.ParseForm()
you can access r.Form
which holds a map[string][]string
of the parsed form data. This map can be accessed by using keys (your form field names):
r.ParseForm()
form := r.Form
someField := form["someField"]
anotherField := form["anotherField"]
or loop through all available keys/ values:
r.ParseForm()
form := r.Form
for key, value := range form {
fmt.Println("Key:", key, "Value:", value)
}
Update
In case you want a more generic solution take a look at the reflect
package. Just to give you a rough example it could look like this:
v := url.Values{}
v.Set("Title", "Your Title")
v.Set("Content", "Your Content")
v.Set("Language", "English")
v.Set("Expires", "2015")
v.Set("Created", "2014")
paste := Paste{}
ps := reflect.ValueOf(&paste)
s := ps.Elem()
for key, value := range v {
f := s.FieldByName(key)
if f.IsValid() && f.CanSet() {
switch f.Kind() {
case reflect.String:
f.SetString(value[0])
case reflect.Int64:
i, _ := strconv.ParseInt(value[0], 0, 64)
f.SetInt(i)
}
}
}