Your render
function accepts a http.ResponseWriter
and a string
. You are trying to pass it a http.ResponseWriter
, a string
and a []App
.
The short answer is that you should change your function to accept a map[string]interface
that you can pass to ExecuteTemplate
. This is useful when you want to pass more than one thing to a template later.
func render(w http.ResponseWriter, tmpl string, data map[string]interface{}){
tmpl = fmt.Sprintf("templates/%s", tmpl)
t, err := template.ParseFiles(tmpl)
if err != nil{
log.Print("template parsing error: ", err)
}
// We pass our data map to the template
err = t.Execute(w, data)
if err != nil{
log.Print("template executing error: ", err)
}
}
... and call it like so:
render(w, "myapps.html", map[string]interface{}{
"apps": apps
})
The long answer is that:
You are establishing a new database pool on every request. Not good! Create either a global pool (okay;
sql.DB
has locks) or by passing a*sql.DB
to your handlers.You are re-parsing your templates on every request. This is slow and inefficient. Parse them once on start-up as per http://golang.org/doc/articles/wiki/#tmp_6
You can write a shortcut for
map[string]interface{}
by writing outtype M map[string]interface{}
, which will allow you to instead writerender(w, "myapps.html", M{"apps": apps})
You should split your DB query out into its own function so you can re-use it elsewhere.
sqlx can help you from having to
rows.Scan()
things yourself - it's a nice convenience wrapper arounddatabase/sql
.
Updated
I've managed to compile your code (for the most part) on my machine, and don't have any panics. I suggest you read the whole stack trace, including the bit above the nil pointer deference/memory address, which may be something along the lines of "template parsing error" (is your filename correct?).
http://play.golang.org/p/QZ65eP-Aln (I've commented out the database stuff)
You will need to fix your templates to have {{ range .apps }}
, however that won't be the source of the panic.
<html>
<body>
<table class="table">
<tr>
<th>Título</th>
<th>Imagen</th>
<th>Descripción</th>
</tr>
{{ range .apps }}
<tr>
<td>{{ .Title }}</td>
<td>{{ .Author }}</td>
<td>{{ .Description }}</td>
<td> <form action="/delete">
<p class="navbar-form navbar-right"><button type="submit" class="btn btn-danger">Borrar</button> </p>
</form></td>
</tr>
{{ end }}
</table>
</body>
</html>