2

I have an array of products. Here is my HomeHandler method where gets the list of products and send it to the home.html.

func (f *FrontendServer) HomeHandler(w http.ResponseWriter, h *http.Request) {
    products := ListProducts()
    parsedTemplate, _ := template.ParseFiles("templates/home.html")
    fmt.Printf("type of product %T\n", products)
    fmt.Println("PRODUCTS\n", products)
    err := parsedTemplate.Execute(w, products)
    if err != nil {
        log.Fatal("Error executing template:", err)
    }
}

This is my home.html file.

<html>
  <head>
    <meta charset="utf-8">
    <title>First Template</title>
    <link rel="stylesheet" href="/static/styles/home.css">
  </head>
  <body>
  <ul>
    {{range .products}}
    <li>
      {{$.name}}
    </li>
     {{end}}
  </ul>
  </body>
</html>

I have tried bunch of techniques like $.Products, .Products, etc. It gives me an error all the time when I make a request to the homepage as below:

2021/05/17 00:19:26 Error executing template:template: home.html:9:12: executing "home.html" at <.products>: can't evaluate field products in type []main.Product

When I print the products its type is as below.

[{1001 Product 1 A product 12.99} {1002 Product 2 A product 13.99} {1003 Product 3 A product 14.99} {1004 Product 4 A product 15.99} {1005 Product 5 A product 16.99} {1006 Product 6 A product 18.99} {1007 Product 7 A product 19.99} {1008 Product 8 A product 20.99} {1009 Product 9 A product 21.99} {1010 Product 1 A product 22.99}]

And here is my Product struct:

type Product struct {
    ID          int     `json:"product_id"`
    Name        string  `json:"product_name"`
    Description string  `json:"product_description"`
    Price       float32 `json:"product_price"`
}

I want to list all products in <li> tags. How can I iterate through all items in this scenario?

1 Answer 1

5

The expression

{{range .products}}

looks for a variable named products in ., where . is the current context, which, at the top level, is the argument to Execute. Based on the error, you are already passing a products array. So, do one of the following:

Either:

{{range .}}

which means, range over the products array passed to Execute, or

    err := parsedTemplate.Execute(w, map[string]interface{}{"products":products})

This will create a map containing products, which is an array, so {{range .products}} will work.

Sign up to request clarification or add additional context in comments.

1 Comment

Also, just to add to your answer Burak, inside the range it should be {{.Name}} and not {{$.name}} as baris attempts. Case matters and $. is the root context, not the iteration variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.