Reputation: 6960
Given below struct, I want to access field2
while iterating over field1
data in html. How do I do this?
var MyPageData struct {
field1 []Foo
field2 map[string]Bar
}
I tried: Inside Handler function:
err := myPageTemplate.Execute(w,MyPageData{ field1: field1Slice, field2 : myMapData})
Template:
{{ range $index, $fooInstance := .field1}}
<tr>
<td>{{$fooInstance.Name}}</td> //This prints the Name value
<td>{{ index .$field2 "myKey".Name }}</td>
How do I access field2
above and specify a key value to retrieve Bar
instance?
UPDATE Adding Foo and Bar structs
type Foo2 struct {
Name string
Id int
}
type Foo struct {
Name string
element Foo2
}
type Bar struct {
Name string
}
Upvotes: 2
Views: 3577
Reputation: 417472
No matter what the value of the pipeline is (which is denoted by the dot .
in the template), you can use the $
to refer to the data value you passed to Template.Execute()
. The {{range}}
action iterates over the elements and it sets the pipeline (.
) to the current item, so .
always denotes the current item, $
is absolutely refers to the "top level" data passed to Template.Execute()
.
This is documented in text/template
:
When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.
Also note that you have to export struct fields to be available in templates. So change your MyPageData
type to:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
Also note that you can simply access map elements using the .
operator. So you can access the value of the Field2
map associated with the "myKey"
key like this, inside the {{range}}
action too:
{{$.Field2.myKey}}
See this simple example:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
type Foo struct {
Name string
}
type Bar struct {
Name string
}
func main() {
t := template.Must(template.New("").Parse(templ))
mpd := MyPageData{
Field1: []Foo{{"First"}, {"Second"}},
Field2: map[string]Bar{"myKey": {"MyValue"}},
}
t.Execute(os.Stdout, mpd)
}
const templ = `{{range $idx, $foo := .Field1}}{{$.Field2.myKey}} {{$idx}} - {{$foo.Name}}
{{end}}`
Output (try it on the Go Playground):
{MyValue} 0 - First
{MyValue} 1 - Second
Also note that insdie the {{range}}
instead of $foo.Name
you can simply use {{.Name}}
as the dot .
denotes $foo
, the current item.
If you want to lookup a value from Field2
with a dynamic key, you do need to use the {{index}}
action. For example if you want the value associated with the key being $foo.Name
:
{{index $.Field2 $foo.Name}}
Or short:
{{index $.Field2 .Name}}
And going forward, if the value associated with the key is a struct for example, and you only need a field of this struct, let's say Id
, you can use parenthesis:
{{(index $.Field2 .Name).Id}}
Upvotes: 4