In your example if your form submit is directed to the validate() handler which will send back an HTTP response (which will be a redirect), the browser will make another call to /register. There is no connection between your validate() handler and your register() handler, the *http.Request value will not be the same as the browser makes another HTTP request and so another *http.Request value will be created and passed on the second call.
You could specify parameters in the redirect URL, e.g. redirect to /register?someParam=someValue but that is just an unnecessary round-trip and complicates things.
An easier solution is to not separate form render and validation (on the handler level). The same handler can take care of both, so no data sharing is required between 2 handlers.
Example:
func register(w http.ResponseWriter, r *http.Request) {
// Params for rendering the page
m := map[string]interface{}{}
// Is form submitted?
if r.FormValue("submitRegister") != "" {
// check submitted values
// E.g. check email, let's say it's already in use:
email := r.FormValue("Email")
if alreadyInUse {
m["Error"] = "Email already in use!"
}
if m["Error"] == "" {
// If all values are OK, create user, and redirect:
http.Redirect(w, r, "/home", http.StatusFound)
return // AND return!
}
// Store submitted values in params, so when we render
// the registration form again, we fill submitted params as initial values,
// so user don't have to fill everything again (expect maybe the password)
m["Email"] = email
}
// Either no submit or validation errors
// Render the registration form, using submitted values as initial ones
// Also if m["Error"] is set, render the error above the form
registerTempl.Execute(w, m)
}
Of course you can break it down to functions, and you can have a separate validate() function, but still the form submit have to point to the same path as your register page (e.g. /register):
func register(w http.ResponseWriter, r *http.Request) {
// Params for rendering the page
m := map[string]interface{}{}
// Is form submitted?
if r.FormValue("submitRegister") != "" {
validate(w, r, m)
if m["Error"] == "" {
return // AND return!
}
}
// Either no submit or validation errors
// Render the registration form, using submitted values as initial ones
// Also if m["Error"] is set, render the error above the form
registerTempl.Execute(w, m)
}
func validate(w http.ResponseWriter, r *http.Request, m map[string]interface{}) {
// check submitted values
// E.g. check email, let's say it's already in use:
email := r.FormValue("Email")
if alreadyInUse {
m["Error"] = "Email already in use!"
}
if m["Error"] == "" {
// If all values are OK, create user, and redirect:
http.Redirect(w, r, "/home", http.StatusFound)
return
}
// Store submitted values in params, so when we
// render the registration form again, we fill submitted params as initial values,
// so user don't have to fill everything again (expect maybe the password)
m["Email"] = email
}