1

I'm new to Go Templates and I'm trying to access the first element in a SortedPair list. I tried {{ (index .Labels.SortedPairs 1)}}{{ .Name }} = {{ .Value }} but that's not working, I'm getting can't evaluate field Name in type template.Alert.

Is there a way to get the very first element? When it's a {{range}}, it works fine but displays too many elements.

Thanks

icza
  • 389,944
  • 63
  • 907
  • 827
iso123
  • 89
  • 1
  • 3
  • 9
  • You can create a function or method that returns the first pair, and call it from the template. See http://stackoverflow.com/questions/10200178/call-a-method-from-a-go-template – RayfenWindspear Apr 06 '17 at 15:43

1 Answers1

2

Note that the first index is 0 and not 1.

You may index the list both when displaying its Name and Value:

{{(index .Labels.SortedPairs 0).Name}} = {{(index .Labels.SortedPairs 0).Value}}

It's shorter if you assign it to a variable though:

{{$first := index .Labels.SortedPairs 0}}{{$first.Name}} = {{$first.Value}}

And even clearer if you use the {{with}} action:

{{with index .Labels.SortedPairs 0}}{{.Name}} = {{.Value}}{{end}}

Let's test the 3 variants:

type Pair struct {
    Name, Value string
}

var variants = []string{
    `{{$first := index .SortedPairs 0}}{{$first.Name}} = {{$first.Value}}`,
    `{{(index .SortedPairs 0).Name}} = {{(index .SortedPairs 0).Value}}`,
    `{{with index .SortedPairs 0}}{{.Name}} = {{.Value}}{{end}}`,
}

m := map[string]interface{}{
    "SortedPairs": []Pair{
        {"first", "1"},
        {"second", "2"},
    },
}

for _, templ := range variants {
    t := template.Must(template.New("").Parse(templ))
    if err := t.Execute(os.Stdout, m); err != nil {
        panic(err)
    }
    fmt.Println()
}

Output (try it on the Go Playground):

first = 1
first = 1
first = 1
icza
  • 389,944
  • 63
  • 907
  • 827