Reputation: 55
I am attempting to pass a struct containing multiple slices of structs into a template. Is there a way to refactor the template so that I can display all the data with using only a single loop (so as to avoid copying and pasting for every single Stock struct that I have). I have tried passing in a 2d array and was unable to access the elements I needed and haven't been able to refactor the template to only one use loop myself.
The following code is a simplified version of what I'm working with.
package main
import (
"fmt"
"html/template"
"os"
)
type Stock struct {
BuyPrice string
SellPrice string
}
type StockPortfolio struct {
StockA []Stock
StockB []Stock
}
func main() {
// Stocks aren't combined from the get-go because I have more
// struct fields relating to each individial trading pair
stockAUSD := Stock{
BuyPrice: "1.00 USD",
SellPrice: "1.10 USD",
}
stockAEURO := Stock{
BuyPrice: "0.85 EUR",
SellPrice: "0.94 EUR",
}
stockBUSD := Stock{
BuyPrice: "2.00 USD",
SellPrice: "2.10 USD",
}
stockBEURO := Stock{
BuyPrice: "1.70 EUR",
SellPrice: "1.88 EUR",
}
stockA := []Stock{stockAUSD, stockAEURO}
stockB := []Stock{stockBUSD, stockBEURO}
portfolio := StockPortfolio{stockA, stockB}
tmpl := `
<table>
<tr>
<td>Price A</td>
{{range .StockA}}
<td>{{ .BuyPrice }}</td>
<td>{{ .SellPrice }}</td>
{{end}}
</tr>
<tr>
<td>Price B</td>
{{range .StockB}}
<td>{{ .BuyPrice }}</td>
<td>{{ .SellPrice }}</td>
{{end}}
</tr>
</table>
`
t := template.Must(template.New("tmpl").Parse(tmpl))
err := t.Execute(os.Stdout, portfolio)
if err != nil {
fmt.Println("executing template:", err)
}
}
Upvotes: 1
Views: 692
Reputation: 618
This template should do want you want; it range
s over your first and second slice and print all the stock information:
<html>
<body>
<h1>All Stocks</h1>
<table>
{{ range $key, $val := . }}
<tr>
<td>Portfolio Number: {{ $key }}</td>
</tr>
<tr>
<td>Buy Price</td>
<td>Sell Price</td>
</tr>
{{ range $val2 := . }}
<tr>
<td>{{ $val2.BuyPrice }}</td>
<td>{{ $val2.SellPrice }}</td>
</tr>
{{ end }}
{{ end }}
</table>
</body>
</html>
But this solution requires a little bit of restructuring. That is, a Portfolio
is now a slice of slices of Stock
s:
// Portfolio is a slice of slices of stocks
type Portfolio [][]Stock
....
stockA := []Stock{stockAUSD, stockAEURO}
stockB := []Stock{stockBUSD, stockBEURO}
portfolio := Portfolio([][]Stock{stockA, stockB}) // for illustrative purposes
....
This should give you a nicely formatted table without the necessity to manually loop over all Stock
s.
Upvotes: 0