Question

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"]}

Was it helpful?

Solution

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

}

OTHER TIPS

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)
        }
    }
}

Play

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top