Home > other >  Looping through array elements in GoLang in the html/template
Looping through array elements in GoLang in the html/template

Time:09-27

I have a Go web server where I would like to display the contents of a JSON file..

The main.go reads the file and puts the data into a struct. When I loop through the data in the struct directly, I can print the data in the terminal like this:

Group 1

Member1

Member2

Member3

Group2

Member1

Member2

Member3

Which is what I want in my html so that I can style it.

When I send the data to the template, I get the following

Group1

[Member1 Member2 Member3]

Group2

[Member1 Member2 Member3]

It looks to me like the GroupMembers are coming in as one string. I would like to know how I can get the template to read them as individual elements so that I can add html (e.g. a <br>).

My code consists of the following 3 files.

The main.go file:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "html/template"
    "io/ioutil"
    "net/http"

    "github.com/dimchansky/utfbom" //used for removing BOM from utf-8
)

//import struct
type dataStruct struct {
    GroupName    string   `json:"name"`
    GroupMembers []string `json:"Members"`
}

type Request struct {
}

//File path
const jsonImport = "./static/JSONFiles/OUdata.json"

func main() {

    http.HandleFunc("/", pageHandler)
    http.ListenAndServe(":2323", nil)
}

func pageHandler(w http.ResponseWriter, r *http.Request) {
    //read file
    theJson, err := ioutil.ReadFile(jsonImport)
    if err != nil {
        fmt.Print(err)
    }
    //get rid of BOM
    data, err := ioutil.ReadAll(utfbom.SkipOnly(bytes.NewReader(theJson)))
    if err != nil {
        fmt.Println(err)
        return
    }

    //make a new struct
    var theData []dataStruct

    //put the JSON into a struct
    err = json.Unmarshal(data, &theData)
    if err != nil {
        fmt.Println("error!!", err)
    }

    //loop through and print JSON in terminal
    for i := 0; i < len(theData); i   {
        fmt.Println(theData[i].GroupName)
        for j := 0; j < len(theData[i].GroupMembers); j   {
            fmt.Println(theData[i].GroupMembers[j])
        }

    }
    //Print test of 1 GroupMember in terminal
    fmt.Println(theData[0].GroupMembers[1])

    p := theData
    t, _ := template.ParseFiles("rolegrouppage.html")
    t.Execute(w, p)
}

The html template file (rolegrouppage.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hiya Buddy!</title>
</head>
<body>
  {{range .}}
  <h1>
    {{.GroupName}}
</h1>

<h4>
  
  {{.GroupMembers}}
  
</h4> 

{{end}}

</body>
</html>

And the data file (OUdata.json):

[
    {
        "name":  "Group 1",
        "Members":  [
                        "Mrs Smith",
                        "Ms Sigmundsdottir",
                        "Mr Arnason"
                    ]
    },
    {
        "name":  "Group 2",
        "Members":  [
                        "Mrs Gunnarsdottir",
                        "Mr Bjarnason",
                        "Ms Sturludóttir",
                        "Mrs Grímsdóttir",
                        "Mr Rafnkelsson"
                    ]
    }
]

Would the best way to achieve this be to reformat the JSON file and somehow loop through it differently? Or is there a way to access each "element" from the html/template?

CodePudding user response:

You need to range over the GroupMembers field, just like you are ranging over the theData value.

<body>
{{ range . }}
  <h1>{{ .GroupName }}</h1>
  {{ range .GroupMembers }}
  <h4>{{ . }}</h4>
  {{ end }}
{{ end }}
</body>
  • Related