如何使用gin-templating发送地图数组并对其进行迭代
Following is the snippet of a working code. I am using gin templating engine.
c.HTML(200, "index", gin.H{
"title": "Welcome",
"students": map[int]map[string]string{1: {"PID": "1", "Name": "myName"}},})
And in index template I have:
<TABLE class= "myTable" >
<tr class="headingTr">
<td>Name</td>
</tr>
{{range $student := .students}}
<td>{{$student.Name}}</td>
{{end}}
</TABLE>
As you can see I have hard-coded the value of students
on the headers (the map). I want to have this data from a rest API that I have built. the response of my rest API is an array:
[
{
"id": 1,
"name": "Mary"
},
{
"id": 2,
"name": "John"
}
]
I can unmarshal this JSON response into map[string]string
instead of map[int]map[string]string
. How can pass this unmarhsaled body in parameter value for students and then iterate over this array the index template?
With a struct
What you have is a JSON array, unmarshal it into a Go slice. Recommended to create a Student
struct to model your students to have a clean and conscious Go code.
And in the template the {{range}}
action sets the dot .
to the current element, you can refer to it inside the {{range}}
body simply as the dot .
, so the student name will be .Name
.
Working code (try it on the Go Playground):
func main() {
t := template.Must(template.New("").Parse(templ))
var students []Student
if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
panic(err)
}
params := map[string]interface{}{"Students": students}
if err := t.Execute(os.Stdout, params); err != nil {
panic(nil)
}
}
const jsondata = `[
{
"id": 1,
"name": "Mary"
},
{
"id": 2,
"name": "John"
}
]`
const templ = `<TABLE class= "myTable" >
<tr class="headingTr">
<td>Name</td>
</tr>
{{range .Students}}
<td>{{.Name}}</td>
{{end}}
</TABLE>`
Output:
<TABLE class= "myTable" >
<tr class="headingTr">
<td>Name</td>
</tr>
<td>Mary</td>
<td>John</td>
</TABLE>
With a map
If you don't want to create and use a Student
struct, you can still do it with a simple map whose type is map[string]interface{}
which can represent any JSON object, but know that in this case you have to refer to students' names as .name
as that is how it appears in the JSON text, and so lowercased "name"
key will be used in the unmarshaled Go map:
func main() {
t := template.Must(template.New("").Parse(templ))
var students []map[string]interface{}
if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
panic(err)
}
params := map[string]interface{}{"Students": students}
if err := t.Execute(os.Stdout, params); err != nil {
panic(nil)
}
}
const templ = `<TABLE class= "myTable" >
<tr class="headingTr">
<td>Name</td>
</tr>
{{range .Students}}
<td>{{.name}}</td>
{{end}}
</TABLE>`
Output is the same. Try this variant on the Go Playground.