What if you want to to render two objects to be rendered within one template?

Hi, Let’s say I have two result set from database which I’ve already added to array sucessfully:
resA and resB
I want to render them within one template by executing:
tmpl1.ExecuteTemplate(w, "Index", resA, resB) But it wil fail I know.
How these type of things are done in go template?

In my template I want to access them like this:

{{range .ResA}}
resA field-1 is: {{.resA-f1}}
resA field-2 is {{.resA-f2}}
{{end}}

{{range .ResB}}
resB field-1 is: {{.resB-f1}}
resB field-2 is {{.resB-f2}}
{{end}}

Give your template one top level object that contains the other things, for example a map:

tmpl1.ExecuteTemplate(w, "Index", map[string]interface{}{
  “resA”: resA,
  “resB”: resB,
})

It can be more strictly typed, and it could also be a struct.

2 Likes

Thank you @calmh, I have a code below, I am trying to give my template one top level object that contains the other things. In my case I want to give to Data struct both res and resm arrays.
I know I am missing something and getting an error:

# command-line-arguments
./main.go:132:36: cannot use &res (type *[]Year) as type *Year in array or slice literal
./main.go:133:37: cannot use &resm (type *[]Month) as type *Month in array or slice literal

I am doing it in a right way or is there a better way to do this?
Thank you in advance for your help.

type Month struct {
    Mname string
    Color string
    Id  int
}


type Year struct {
    Yname, Color string
    Selected bool
}

type Data struct {
        Years   []*Year
        Months  []*Month
}


var tmpl3 = template.Must(template.ParseGlob("report/*"))

func ShowMonth(w http.ResponseWriter, r *http.Request) {
    db := dbConn()
///////////////////////////////////////////////////////////////////////////
    if r.Method == "POST" {
       years := r.FormValue("years")
 
    selDB, err := db.Query("SELECT MONTHNAME(Rdate) as months, color, report_monthly_id as id FROM report_monthly WHERE YEAR(Rdate)=?", years )
    if err != nil {
        panic(err.Error())
    }
    resm := []Month{}
    for selDB.Next() {
        var months, color string
        var id int
        err = selDB.Scan(&months, &color, &id)
        if err != nil {
            panic(err.Error())
        }
        
        rep := Month{Mname: months, Color: color, Id: id}
        resm = append(resm, rep)


    }    
///////////////////////////////////////////////////////////////////////////
    

    selDB1, err := db.Query("SELECT DISTINCT YEAR(Rdate) as years, color FROM report_monthly  ORDER BY report_monthly_id DESC")
    if err != nil {
        panic(err.Error())
    }
    res := []Year{}
    for selDB1.Next() {
        var years, color string
        err = selDB1.Scan(&years, &color)
        if err != nil {
            panic(err.Error())
        }

        rep := Year{Yname: years, Color: color}
        res = append(res, rep)
    }

    // f2 := Month{Mname: "FEB", Color: "BLUE"}
    // f3 := Year{Yname: "2018", Selected: false}
   
    person := Data{Years:  []*Year{&res},
                   Months: []*Month{&resm}}

    // log.Println(resm)
    log.Println(person)
    tmpl3.ExecuteTemplate(w, "IndexReport", person)
    defer db.Close()
}
}

There is still confusion about structs, slices, slices of structs, and pointers to slices. I think you need to back up a few steps, go through the basics once more to make sure you understand the involved types. Then the templating stuff will make sense.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.