I've seen some similar questions but I can't find one that solves my problem.
I have a custom Money
type that aliases int64 with a function that formats the value as a string:
type Money int64
func (m *Money) Format() string {
abs := math.Abs(int64(*m))
dollars := int64(abs) / 100
cents := int64(abs) % 100
sign := ""
if *m < 0 {
sign = "-"
}
return fmt.Sprintf("%s$%d.%0.2d", sign, dollars, cents)
}
I have a HTML template that I pass a data struct. The struct has a list of invoice items on it that each have a Money field, and another Money field that holds the total.
type InvoiceItem {
// ...
Cost money.Money
}
type data struct {
Name string
Items []*model.InvoiceItem
StartDate time.Time
EndDate time.Time
Total money.Money
}
I pass the data
to my template and execute it:
t := template.Must(template.New(title).Parse(templateString))
t.Execute(&buf, data)
In my template I range over the invoice items and call the Format
function on the Money
object. This works:
{{range .Items}}
<tr>
<td>{{.Description}}</td>
<td>{{.Cost.Format}}</td>
</tr>
{{end}}
Later on I attempt to print the total field:
<td><strong>{{ .Total.Format }}</strong></td>
My templates throws an error:
... executing "Invoice Items" at <.Total.Format>: can't evaluate field Format in type money.Money
Why is it that I can call Format
on the Money
field when I range over the list of invoice items, but I can't call it on the data.Total
object? From the error message it seems that the template knows that the type of Total
is Money
, so what's the problem?