0

I'm trying to make a website to show some data on the index page.
The code snippet below shows my indexHandler function to parse my data.

func indexHandler(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("./templates/indexEx2.html")
if err != nil {
    panic(err.Error())
}
sortedData := sortData()
t.Execute(w, sortedData) }

The problem is that whenever I refresh the page, the elements on the page is duplicated.

This is index.html file.

<body>
<div class="row">
    <div class="column" style="background-color:#FFB695;">
        <h2>Column 1</h2>
        {{range .Artist}}
        <p>{{.}}</p>
        {{end}}
    </div>
    <div class="column" style="background-color:#96D1CD;">
        <h2>Column 2</h2>
        {{range .Title}}
        <p>{{.}}</p>
        {{end}}
    </div>
    <div class="column" style="background-color:#581eb0;">
        <h2>Column 3</h2>
        {{range .Photo}}
        <p>{{.}}</p>
        {{end}}
    </div>
    <div class="column" style="background-color:#11e318;">
        <h2>Column 3</h2>
        {{range .File}}
        <p>{{.}}</p>
        {{end}}
        
    </div>

</div> </body>

How can I solve this?

swk23C8
  • 314
  • 3
  • 10
부건혁
  • 91
  • 7
  • 3
    We need to see `sortData()`. Also don't parse templates in the handler, see [It takes too much time when using "template" package to generate a dynamic web page to client in Golang](https://stackoverflow.com/questions/28451675/it-takes-too-much-time-when-using-template-package-to-generate-a-dynamic-web-p/28453523#28453523) – icza May 01 '22 at 15:47

1 Answers1

0

You can parse all templates in the init function and then only need to execute them in your handlers:

package main

import (
    "html/template"
    "log"
    "net/http"
)

var tmpl *template.Template

func init() {
    tmpl = template.Must(template.ParseGlobe("templates/*"))
}

func main() {
    http.HandleFunc("/", indexHandler)
    log.Fatalf("%s", http.ListenAndServe(":8080", nil))
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    sortedData := sortData()
    if err := tmpl.ExecuteTemplate(w, "index.html", sortedData); err != nil   {
        // Error handling ...
    }
}

In this way, the templates are only parsed once when the application is started.

davidlucius
  • 206
  • 2
  • 4
  • According to [`template.ExecuteTemplate`'s doc](https://pkg.go.dev/html/template#Template.ExecuteTemplate): *If an error occurs executing the template or writing its output, execution stops, but partial results may already have been written to the output writer*. Instead of directly writing to the `http.ResponseWriter`, wouldn't it be better to write to an intermediary buffer, `bytes.Buffer`? If it failed then produce an internal server error response. Otherwise, just dump this buffer into `w` with [`WriteTo()`](https://pkg.go.dev/bytes#Buffer.WriteTo). What do you think? – JFMR May 02 '22 at 07:39