How to use Go html/template to iterate through a map

In this example we'll use Golang's html/template package and iterate through a map in our html template.

You can check out a working example of this code in the Go Playground.

Let's say we have the following structs:

	type Employee struct {
		FirstName string
		LastName  string
		Email     string
	}

	type Content struct {
		Department   string
		Employees map[string]Employee
	}

The Content struct is what we want to display in our html template. It contains a Department string and a map containing Employees.

Let's populate the struct with one department and employees:

var c Content
	c.Department = "Sales"
	c.Employees = make(map[string]Employee)
	c.Employees["bSmith"] = Employee{
        FirstName: "Bob",
        LastName: "Smith",
        Email: "bob@smith.com"
        }
	c.Employees["mBrown"] = Employee{
        FirstName: "Michael",
        LastName: "Brown",
        Email: "michael@brown.com"
        }
	c.Employees["hTennenbaum"] = Employee{
        FirstName: "Harry",
        LastName: "Tennenbaum",
        Email: "harry@tennenbaum.com"
        }

How do we iterate through the map in our template and display each element of our struct Employees? We make use of range.

html := `{{define "departments"}}
<ul>
  <li>{{.Department}}</li>
  {{range $key, $value := .Employees}}
    <li>{{$value.FirstName}} {{(index $.Employees $key).LastName}} {{$value.Email}}</li>
  {{end}}
</ul>
{{end}}`

We use range $key, $value := .Employees to get all the keys and values of the Employees map. We can then use $value to reference the Employee struct directly.

{{$value.FirstName}}

We can also use the index keyword to reference the Employee struct using the $key as our key:

{{(index $.Employees $key).FirstName}}

Using index is the equivalent of writing this in Go:

c.Employees["someKey"].FirstName

If you have any questions with this solution, or you can see a mistake I have made, please DM me on twitter.