LoginSignup
0
0

Golangでネストされた構造体のスライスの中身をHTMLで表示する方法(rangeの挙動について)

Posted at

この記事を読んでわかること

  • ネストされた構造体のスライスの中身をhtmlに表示させるための書き方
  • 実際に実装してみるためのサンプルコード

サンプルコード(main.go, template.html)

先にサンプルコードを示しておく。今回はmain.goファイルとtemplate.htmlを使用する。Pathについては各自改めて設定していただきたい。

main.go
package main

import (
	"html/template"
	"net/http"
	"log"
)

type User struct {
	ID      int
	Name    string
	Email   string
	Todos   []Todo
}

type Todo struct {
	Title   string
	Content string
	Done    bool
}

func generateHTML(w http.ResponseWriter, data interface{}) {
	tmpl := template.Must(template.ParseFiles("templates/template.html"))
	err := tmpl.Execute(w, data)
	if err != nil {
		log.Println(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}
}

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		user := User{
			ID:    1,
			Name:  "John Doe",
			Email: "john@example.com",
		}

		todo1 := Todo{
			Title:   "Task 1",
			Content: "Do task 1",
			Done:    false,
		}
	
		todo2 := Todo{
			Title:   "Task 2",
			Content: "Do task 2",
			Done:    true,
		}

		user.Todos = append(user.Todos, todo1)
		user.Todos = append(user.Todos, todo2)
		generateHTML(w, user)
	})

	log.Println("Server started on localhost:8080")
	http.ListenAndServe(":8080", nil)
}

templates/template.html
<!DOCTYPE html>
<html>

<head>
    <title>User Information</title>
</head>

<body>
    <h1>User Information</h1>
    <p>ID: {{ .ID }}</p>
    <p>Name: {{ .Name }}</p>
    <p>Email: {{ .Email }}</p>
    <h2>Address</h2>
    {{ range .Todos}}
    <p>Title: {{ .Title }}</p>
    {{end}}
</body>

</html>

設定の確認

構造体について確認しておく。

main.go
type User struct {
	ID      int
	Name    string
	Email   string
	Todos   []Todo
}

type Todo struct {
	Title   string
	Content string
	Done    bool
}

ここではUserという構造体とTodoという構造体を定義している。
Userという構造体には、ID, Name, Email, Todosというフィールドが存在していることがわかる。
ただTodosがスライス型であることに注意していただきたい。
また、Todoという構造体には、Title, Content, Doneというフィールドが存在する。

main.go
user := User{
			ID:    1,
			Name:  "Tarou",
			Email: "Tarou@example.com",
		}

todo1 := Todo{
	Title:   "Task 1",
	Content: "Do task 1",
	Done:    false,
}
	
todo2 := Todo{
	Title:   "Task 2",
	Content: "Do task 2",
	Done:    true,
}
user.Todos = append(user.Todos, todo1)
user.Todos = append(user.Todos, todo2)

ここでは、TarouのTodoを2つ作成している。
そして、main.goファイルで

main.go
generateHTML(w, user)

このように書いたことでuser、つまりTarouの情報がhtmlに渡されている。

本題

ここでやりたいことはTarouのTodosの中のTitleを並べて表示するということである。

そこで使用するのがrangeである。
htmlの中で以下のように指定する。

template.html
{{ range .Todos }}
    <p>Title: {{ .Title }}</p>
{{end}}

{{ range .Todos }}と{{end}}で括った部分がTodosの長さ分繰り返される。
そして、特に注意しなければならないのがTitleの取り出し方である。
一般的にネストされた構造体の中身を見るときは、

{{ .Todos.Title }}

とすることで確認することができるが、rangeを使う場合はその中で.Todosは不要になり、

{{ .Title }}

のみで使用することになる。

私はそれがわからず数時間悪戦苦闘することになってしまったが、皆さんはそのようなことがないことを祈っている。

最後に

初めてのQiita記事で読みにくいところがあったかもしれませんが、最後まで読んでいただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0