简体   繁体   中英

Multiple response.WriteHeader calls

I am new to go and have difficulty rendring templates.

Here is my functions that are to generate template:

base.html

//Render templates for the given name, template definition and data object
func renderTemplate(w http.ResponseWriter, name string, template string, viewModel interface{}) {
    // Ensure the template exists in the map.
    tmpl, ok := templates[name]
    if !ok {
        http.Error(w, "The template does not exist.", http.StatusInternalServerError)
    }
    err := tmpl.ExecuteTemplate(w, template, viewModel)
    if err != nil {
    log.Printf("temlate error here")
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}


 func EditNote(w http.ResponseWriter, r *http.Request) {
    //var viewModel models.EditChnl
    vars := mux.Vars(r)
    //ch := bson.M{"id": "Ale"}
    title := vars["title"]
    log.Printf("%v\n", title)
    session, err := mgo.Dial("localhost")
    if err != nil {
      panic(err)
    }
        defer session.Close()
        session.SetMode(mgo.Monotonic, true)
        c := session.DB("tlgdb").C("chnls")
        log.Printf("title is %s \n", title)
        var result  []models.Chnl
        err = c.Find(bson.M{"title": "xxx"}).All(&result)
        log.Printf("%v\n", result)

        if err != nil {
          log.Printf("doc not found")
          log.Fatal(err)
          return
        }
    renderTemplate(w, "edit", "base", result)
}

And here are the templates:

{{define "base"}}
<html>
  <head>
    {{template "head" .}}
  </head>
  <body>

    {{template "body" .}}

  </body>
</html>
{{end}}

edit.thml

{{define "head"}}<title>Edit Note</title>{{end}}
{{define "body"}}
<h1>Edit Note</h1>
<form action="/chnls/update/{{.Title}}" method="post">
<p>Title:<br> <input type="text" value="{{.Title}}" name="title"></p>
<p>Description:<br> <textarea rows="4" cols="50" name="description">{{.Description}}</textarea> </p>
<p><input type="submit" value="submit"/></p>
</form>
{{end}}

The objects to render are:

type Chnl struct {
    Id    bson.ObjectId `json:"id"  bson:"_id,omitempty"`
    Title       string
    Description string
    CreatedOn   time.Time
    Creator     string
    Visits  int
    Score       int
}

The object that I'm trying to render exists in mongodb and I can print it out in console:

[{ObjectIdHex("56cc4493bc54f4245cb4d36b") sometitle blabla 2016-02-23 12:37:55.972 +0100 CET blabla 0 0}]

However I get this error:

temlate error here
http: multiple response.WriteHeader calls

I'm wondering what is wrong here and how to fix it?

The root problem is that you pass a slice of Chnl to the template:

var result  []models.Chnl
// ...
renderTemplate(w, "edit", "base", result)

And inside renderTemplate() param value of viewModel will be result .

And in your templates you refer to fields of the dot like if it would be a Chnl value and not a slice of it: {{.Title}} . So the first attempt to resolve it will fail.

Logging the errors is useful, so change your logging to also print the actual error, not just a generic error:

log.Printf("Temlate error here: %v", err)

Which results in:

2016/02/24 14:57:09 Temlate error here: template: edit.html:4:30: executing "body" at <.Title>: can't evaluate field Title in type []main.Chnl

I think you just want to pass 1 Chnl value and not a slice of them. In EditNote() :

if len(result) > 0 {
    renderTemplate(w, "edit", "base", result[0])
}

Next, know that http.Error() writes content to the response. This means you cannot write further header values to the response. Usually when you call http.Error() in your handler, you should return without doing anything with the response:

if !ok {
    http.Error(w, "The template does not exist.", http.StatusInternalServerError)
    return // NOTE THIS RETURN
}

Similarly, after all your http.Error() call insert a return . You may do some cleanup, but response should not be touched after http.Error() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM