Handling Multiple Form Values in Go

When a POST request contains multiple values for the same key (e.g., checkboxes or multi-selects), follow these patterns.

1. Standard Form (application/x-www-form-urlencoded)

Use r.PostForm to get a slice of all values.

func handler(w http.ResponseWriter, r *http.Request) {
    // 1. Parse the form
    if err := r.ParseForm(); err != nil {
        http.Error(w, "Error parsing form", http.StatusBadRequest)
        return
    }

    // 2. Access the slice directly (map[string][]string)
    tags := r.PostForm["tags"] 
    
    for _, tag := range tags {
        fmt.Printf("Value: %s\n", tag)
    }
}

2. Multipart Form (multipart/form-data)

Required if you are also uploading files.

func handler(w http.ResponseWriter, r *http.Request) {
    // Parse with max memory limit (e.g., 32MB)
    if err := r.ParseMultipartForm(32 << 20); err != nil {
        return
    }

    // Access from MultipartForm.Value
    values := r.MultipartForm.Value["tags"]
}

⚠️ Important Note on PostFormValue

Do not use r.PostFormValue("key") if you expect multiple values. It only returns the first value found and discards the rest.

MethodReturn TypeMulti-Value Support
r.PostForm["key"][]string✅ Returns all values
r.PostFormValue("key")string❌ Returns first value only
r.Form["key"][]string✅ Returns all (Query + Body)