Why does not {{range.}} works?

I am trying to understand how html templates works with json. Found an example:

https://play.golang.org/p/EOVypH5ONHn

…and tried to add {{range.}} to it, but it gets errors:

https://play.golang.org/p/vrwx01z0_0o

package main

import (
	"encoding/json"
	"html/template"
	"os"
)

func main() {
	t := template.Must(template.New("").Parse(templ))

	m := map[string]interface{}{}
	if err := json.Unmarshal([]byte(jsondata), &m); err != nil {
		panic(err)
	}

	if err := t.Execute(os.Stdout, m); err != nil {
		panic(err)
	}
}

const templ = `<html><body>
        {{range.}}	
	      {{.something}}
	      {{.somethingElse}}
        {{end}}
</body></html>`

const jsondata = `{"something":"valueofa", "somethingElse": 1234}`

What am I doing wrong? Why does it work without {{range.}}?

If you want to loop over the items in the JSON object, you could do something like this:

const templ = `<html><body>
{{ range $key, $value := . }}
   <li>{{ $key }}: {{ $value }}</li>
{{ end }}
</body></html>`

Output:

<html><body>
   <li>something: valueofa</li>
   <li>somethingElse: 1234</li>
</body></html>

See https://play.golang.org/p/lpRqZPmPsy1

Not exactly. But close.

This should appear as ONE line:

{“something”:“valueofa”, “somethingElse”: 1234}

And this should appear as TWO lines:

{“something”:“valueofa”, “somethingElse”: 1234},
{“something”:“valueofb”, “somethingElse”: 3456}

How do I range over one OR two lines. Sometimes the data only contains one line, so I should work with 1 or many records.

https://play.golang.org/p/cEdfUag-Ywt

What HTML output do you expect?

Also note that

{"something":"valueofa", "somethingElse": 1234},
{"something":"valueofb", "somethingElse": 3456}

is not valid JSON. You could wrap these two objects into a JSON array:

[
  {"something":"valueofa", "somethingElse": 1234},
  {"something":"valueofb", "somethingElse": 3456}
]

You would have to change

m := map[string]interface{}{}

to

m := []map[string]interface{}{}
//   ^^ -- array!

and change the template to

const templ = `<html><body>
{{ range . }}
   <li>{{ .something }}: {{ .somethingElse }}</li>
{{ end }}
</body></html>`

Output:

<html><body>
   <li>valueofa: 1234</li>
   <li>valueofb: 3456</li>
</body></html>

See https://play.golang.org/p/yoJIG42oRGT

Right on spot!

This was my first goal. Thank you!
https://play.golang.org/p/IkSKrHyk0mo

1 Like

Note that the template handles a JSON array. Even if you have only a single JSON object, you have to wrap it into a JSON array for this template to work.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.