如何在Golang中将多个数据对象传递给HTML模板

I am returing all rows of a table as json to the variable pdata and unmarshaling it into an interface object. I have an instance of the user struct which I would like to pass along with the unmarshalled json data to the render function and access it using field arguments {{.fieldname}} in the html template.

if uuid != "" {
    pdata, err := getProduct()
    if err != nil {
        fmt.Println(err)
    } 

    type Prdata struct {
        Puid     string `json:"puid"`
        Pname    string `json:"pname"`
        Quantity string `json:"quantity"`
        Price    string `json:"price"`
        Image    string `json:"image"`
    }

    // Obj:= make(map[Prdata]string)

    var Pr Prdata

    err = json.Unmarshal(pdata , &Pr)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(string(pdata))
    fmt.Println(Pr)
    fmt.Println(u)

    render(w, "internal", Pr)
}

fmt.Println(string(pdata)) gives this output

[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity":"100"}]

I have only been successful to unmarshal the data into an interface{} object. Trying to make maps with keys of the type interface{} and values of type string but it throws the error:

"json: cannot unmarshal array into Go value of type map[interface {}]string"

The render function takes an argument of the type interface{}

func render(w http.ResponseWriter, name string, data interface{})

fmt.Println(Pr) gives this output:

[map[quantity:100 image:1Appleiphone7.jpeg pname:iphone7 price:70000 puid:d6742e4e-2ad6-43c5-97f4-e8a7b00684e2]]

u is an instance of struct User

var u = &User{}

type User struct {
    Uuid     string            
    Username string           
    Password string           
    Fname    string            
    Email    string            
}

I can see the output on the html page using the pipeline {{.}}. However I am not able to access any data using the fieldname.

There must be a way of doing this. But I am not sure how?

When I pass of a json of the type below, I am able to pass it to the struct type and reference it by the key values using pipelines in my template.

    str := `{
    "image": "1Appleiphone7.jpeg",
    "pname": "iphone7",
    "price": "70000",
    "puid": "d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
    "quantity": "100"
    }`

unmarshal function

err = json.Unmarshal([]byte(str), &Pr)

The difference in the json data of the DB record pdata and the one above str is in the use of backticks "`". It seems that though the json data shows key value pairs, it is actually a json array and not a json object. Is there a way to get around this?

I am posting a working example of unmarshalling json as bytes into a struct type which then can be referenced using the {{.}} in the template.

package main

import (
    "encoding/json"
    "fmt"
)

type Usrdata struct {
    Uuid  string
    Fname string
}

type Prdata struct {
    Puid     string `json:"puid"`
    Pname    string `json:"pname"`
    Quantity string `json:"quantity"`
    Price    string `json:"price"`
    Image    string `json:"image"`
}

type Data struct {
    U Usrdata
    P []Prdata
}

func main() {
    Ur := Usrdata{Uuid: "xyz", Fname: "Somename"}
    Pr := make([]Prdata, 0)
    var Dt Data
    Dt.U = Ur
    pdata := `[{"image":"1Appleiphone7.jpeg","pname":"iphone7","price":"70000","puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2","quantity":"100"}]`
    err := json.Unmarshal([]byte(pdata), &Pr)
    if err != nil {
        fmt.Println(err)
    }
    Dt.P = Pr
    fmt.Println(Pr[0].Pname)
    fmt.Println(Pr)
    fmt.Println(Dt)
}

You don't need a map[interface{}]string to unmarshal the json obj. Your json is equivalent to slice of maps:

[
    {
        "image":"1Appleiphone7.jpeg",
        "pname":"iphone7",
        "price":"70000",
        "puid":"d6742e4e-2ad6-43c5-97f4-e8a7b00684e2",
        "quantity":"100"
    }
]

The object to unmarshal should be a slice of maps with string keys and values:

var Pr []map[string]string

Playground

BTW, I believe misunderstanding is hidden there:

The render function takes an argument of the type interface{}

I means not that you must pass a variable of interface{} type there but it means you CAN pass a variable of any type to render function.