Golang html/template "wrong number of args want 1 got 0" using 'call' in template

105 Views Asked by At

I'm developing a Go! application using the html templating built-in library. In my template, the following works:

  {{range .industries }}
  ...
    <td style="text-align:right">{{ .SalesStock.Size }}</td>
  ...
  {{ end }}

industries is a slice of objects of type Industry. SalesStock is a method of Industry and yields an object SalesStock of type Stock, which has a field Size.

This code works fine.

In place of Size I want to call a method that will display either the Size or the Price field, depending on a parameter mode.

The (simplified) method is

func (stock Stock) DisplaySize(mode string) float32 {
    switch mode {
    case `price`:
        return stock.Size
    case `size`:
        return stock.Price
    default:
        panic("unknown display mode requested")
    }
}

I replaced the line in the template with:

   <td style="text-align:right">{{ call .SalesStock.DisplaySize "size" }}</td>

and received the error

  at <.SalesStock.DisplaySize>: wrong number of args for DisplaySize: want 1 got 0

What did I do wrong?

thanks for any offers. I suspect the mistake is elementary. I'm new to Go.

1

There are 1 best solutions below

0
icza On BEST ANSWER

The builtin call is to call a function value. You want to call a method, simply remove call and it'll work:

{{ .SalesStock.DisplaySize "size" }}

You would need call if DisplaySize would be a regular field (of function type) and you'd want to call that.

For example:

type Stock struct {
    Size      float32
    Price     float32
    FuncField func(param string) string
}

func (stock Stock) DisplaySize(mode string) float32 {
    switch mode {
    case `price`:
        return stock.Price
    case `size`:
        return stock.Size
    default:
        panic("unknown display mode requested")
    }
}

func main() {
    const src = `{{.SalesStock.DisplaySize "size"}}
{{.SalesStock.DisplaySize "price"}}
{{ call .SalesStock.FuncField "Foo"}}`

    t := template.Must(template.New("").Parse(src))

    p := map[string]any{
        "SalesStock": Stock{
            Size:      2,
            Price:     3,
            FuncField: func(param string) string { return param + param },
        },
    }

    err := t.Execute(os.Stdout, p)
    if err != nil {
        panic(err)
    }
}

This will output (try it on the Go Playground):

2
3
FooFoo