Priyanka
Priyanka

Reputation: 232

How to pass multiple objects to Go html template

Here are my array of objects,

type PeopleCount []struct{
   Name  string
   Count int
}

type Consultation []struct{
   Name          string
   Opd_count     int
   Opinion_count int
   Req_count     int
}

How should I pass both the objects to html template and arrange them in table?

Upvotes: 3

Views: 898

Answers (2)

Thundercat
Thundercat

Reputation: 120941

Define an anonymous struct with fields for people count and consultations and pass the struct to the template Execute method:

var data = struct {
    PeopleCounts  []PeopleCount
    Consultations []Consultation
}{
    PeopleCounts:  p,
    Consultations: c,
}
err := t.Execute(w, &data)
if err != nil {
    // handle error
}

Use these fields in the template:

{{range .PeopleCounts}}{{.Name}}
{{end}}
{{range .Consultations}}{{.Name}}
{{end}}

Playground example

You can declare a named type for the template data. The advantage of the anonymous type declaration is that knowledge of the template data is localized to the function that invokes the template.

You can also use a map instead of a type:

err := t.Execute(w, map[string]interface{}{"PeopleCounts": p, "Consultations": c})
if err != nil {
    // handle error
}

The disadvantage of using a map is that a typo in the template may not result in an error. For example, ``{{range .PopleConts}}{{end}}` silent does nothing.

The code above assumes that PeopleCount and Consultation are struct types and not slices of anonymous struct types:

type PeopleCount struct {
  Name  string
  Count int
}

type Consultation struct {
  Name          string
  Opd_count     int
  Opinion_count int
  Req_count     int
}

It's usually more convenient to give the element a named type than to give the slice a named type.

Upvotes: 5

Rick-777
Rick-777

Reputation: 10238

If you prefer, define an unexported struct with fields for people count and consultations and pass the struct to the template Execute method:

type viewModel struct {
    PeopleCounts  []PeopleCount
    Consultations []Consultation
}

// ...

var data = viewModel{
    PeopleCounts:  p,
    Consultations: c,
}
err := t.Execute(w, &data)
if err != nil {
    // handle error
}

This approach is broadly similar to @Bravada's answer. It's merely a matter of personal taste whether to use a view-model type explicitly or anonymously.

Upvotes: 1

Related Questions