Search code examples
gotemplatesstreaming

How to write incrementally to html template in go


I'm building a web based data browser called Mavgo Flight. I want large tables from sqlite to print continuously instead of the default behavior of only printing when all the data is available. I tried running the template per row of data which fails.

func renderHTMLTable(w http.ResponseWriter, result *sqlx.Rows) {
    cols, err := result.Columns()
    if err != nil {
        log.Println(err, "renderHTMLTable")
        return
    }
    tmpl, err := template.ParseFiles("./templates/2d.html")
    if err != nil {
        log.Println("template failed", err)
        return
    }
    data := HTMLTable{}
    data.Cols = cols
    for result.Next() {
        cols, err := result.SliceScan()
        if err != nil {
            log.Println(w, err)
            break
        }
        s := make([]string, len(cols))
        for i, v := range cols {
            s[i] = fmt.Sprint(v)
        }
        tmpl.Execute(w, s)
    }
}

Solution

  • I gave up on being clever did exactly what Cerise suggested The function that writes rows incrementally:

    func renderHTMLTable(w http.ResponseWriter, result *sqlx.Rows) {
    cols, err := result.Columns()
    if err != nil {
        log.Println(err, "renderHTMLTable")
        return
    }
    head, err := template.ParseFiles("./templates/head.html")
    if err != nil {
        log.Println("template failed", err)
        return
    }
    row, err := template.ParseFiles("./templates/row.html")
    if err != nil {
        log.Println("template failed", err)
        return
    }
    foot := `  </tbody>
    </table>
    </div>
    
    </body>
    </html>`
    head.Execute(w, cols)
    s := make([]string, len(cols))
    for result.Next() {
        values, err := result.SliceScan()
        if err != nil {
            log.Println(w, err)
            break
        }
    
        for i, v := range values {
            s[i] = fmt.Sprint(v)
        }
        row.Execute(w, s)
    }
    fmt.Fprint(w, foot)
    

    }