Go Json into struct / struct into HTML

I got following struct:

	type Data struct {
			Data1         int
			Data2		int
			ImpData     []struct {
				Title          string
				ID               string
				TextS string
			}
		}
		

I unmarshall the jsoncode into var o

		var o Data
		err = json.Unmarshal(output, &o)
		if err != nil {
			panic(err.Error())
		}

I get the data with a for loop

		for i := 0; i < len(o.ImpData); i++ {
				fmt.Printf(" Test: %+v", o.ImpData[i].Title)
				}

Till this point everything works, but i dont know how to excatly execute the Template with the right parameters and data.

	tmpl, _ := template.ParseFiles("index.html")
	tmpl.Execute(w, o)
	
	
HTML:
<p style="color: black;"> {{ range .ImpData }}  {{ . }}</p>

Try switching your template to something like this:

{{ range .ImpData }}
    <p style="color: black;">{{ .Title }}</p>
{{ end }}

Here’s a complete contrived example to get you going:

package main

import (
	"html/template"
	"os"
	"strconv"
)

type ImpData struct {
	Title string
	ID    string
	TextS string
}

type Data struct {
	Data1   int
	Data2   int
	ImpData []ImpData
}

var htmlTmpl = `{{ range .ImpData }}
    <p style="color: black;">{{ .Title }}</p>
{{ end }}`

func main() {
	// Ignoring errors for brevity. Don't really do this.
	t := template.Must(template.New("test").Parse(htmlTmpl))
	dat := Data{}
	for i := 0; i < 10; i++ {
		dat.ImpData = append(dat.ImpData, ImpData{Title: "test", ID: strconv.Itoa(i), TextS: "test"})
	}
	t.Execute(os.Stdout, dat)
}

You can run it on the go playground:

1 Like

Thanks for your answer and help.

Why you declare 2 structs? This heavily confuses me as i have a struct in struct.
in my case the unmarshalled json is in var o.
And why? dat.ImpData I have o.Impdata[i].Title, o.Impdata[i].TextS etc as my output and this needs to be rendered in the html template.

My brain has a stack overflow by understanding this :smiley:

Data contains a slice of type ImpData instead of an anonymous struct. I just did it that way because when you declare your child struct as an anonymous struct like so:

type Data struct {
	Data1   int
	Data2   int
	ImpData []struct { // What type is this?
		Title string
		ID    string
		TextS string
	}
}

… it makes the initialization of my contrived data more verbose:

for i := 0; i < 10; i++ {
	dat.ImpData = append(dat.ImpData, struct {
		Title string
		ID    string
		TextS string
	}{"test", strconv.Itoa(i), "test"})
}

But it’s in effect the same. You can run it here with the exact same Data struct as in your example:

1 Like

OMG it works, thank you so much for your time and help :slight_smile:

Last question how can i render the Data1 and Data2 from the struct in the html AND the ImpData at the same time?

And lets say i have another independent struct and want so parse it in the same html, how can this work?

For example

type OtherData struct {
	OData1   int
	OData2   int
	BookData []struct {
		Title string
		ID    string
		TextS string
	}
}

How can i render this to the same html?

Try this for the template:

var htmlTmpl = `<h1>Data: {{ .Data1 }}</h1>
{{ range .ImpData }}
    <p style="color: black;">{{ .Title }}</p>
{{ end }}`

If you have similar data I would recommend creating a type/struct that encompasses both ideas. Both of the child records on that struct have a Title, ID, and TextS, right? So you could just extract that to its’ own struct:

type LineItem struct {
	Title string
	ID    string
	TextS string
}
type Data struct {
	Data1   int
	Data2   int
	ImpData []LineItem 
}
type OtherData struct {
	OData1   int
	OData2   int
	BookData []LineItem 
}

To both Data and OtherData have a slice of type LineItem. Something along those lines.

1 Like

Thanks again :slight_smile: Okay but if it has not the the same child records?

Like this

	type Data struct {
		Data1         int
		Data2	int
		ImpData     []struct {
			Title          string
			ID               string
			TextS string
			}
		}

type OtherData struct {
	OData1   int
	OData2   int
	BookData []struct {
		Name string
		ID    string
		Location string
	}
}
		

How i get both data in the same html rendered?

And the other thing:

Dont have i to do something like this but with Data?

dat.ImpData = append(dat.ImpData etc

But this is only the data from ImpData not Data right?
So in my understanding is, i have to append it also?