I'm using golang, with sqlx and I'm trying to show on page the following output:
app_monitor.name | app_domains.name
Basically, it retrieves all monitor.name based on userid and get domain_name from other table. I can't manage to get the domain name from other table. Monitor name retrieval is successful. Should I get the domain_name in model, controller, or template engine?
Here is some fields in my database:
app_monitor: id, name, domain_id
user: id, domain_id
app_domains: id, name
My Model snippet:
type Monitor struct {
ID uint32 `db:"id"` // Don't use Id, use MonitorID() instead for consistency with MongoDB
Name string `db:"name"`
DID uint32 `db:"domain_id"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
Status uint8 `db:"status"`
}
func MonitorByUserID(userID string) ([]Monitor, error) {
var err error
var result []Monitor
switch database.ReadConfig().Type {
case database.TypeMySQL:
err = database.SQL.Select(&result, "SELECT app_monitor.id, app_monitor.name, app_monitor.status FROM app_monitor LEFT JOIN user ON app_monitor.domain_id = user.domain_id WHERE user.id = ?", userID)
default:
err = ErrCode
}
return result, standardizeError(err)
}
My Controller
func MonitorReadGET(w http.ResponseWriter, r *http.Request) {
// Get session
sess := session.Instance(r)
userID := fmt.Sprintf("%s", sess.Values["id"])
monitors, err := model.MonitorByUserID(userID)
if err != nil {
log.Println(err)
monitors = []model.Monitor{}
}
// Display the view
v := view.New(r)
v.Name = "monitor/read"
v.Vars["first_name"] = sess.Values["first_name"]
v.Vars["monitors"] = monitors
v.Render(w)
}
And finally My Template
<table class="table table-striped table-hover">
<tr>
<th scope="col-9">Monitor</th>
<th scope="col-3">Action</th>
</tr>
{{range $n := .monitors}}
<tr>
<td>{{.Name.DomainName}}</td>
<td><a title="Edit Monitor" class="btn btn-warning" role="button" href="{{$.BaseURI}}monitor/update/{{.MonitorID}}">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
</a>
<a title="Delete Monitor" class="btn btn-danger" role="button" href="{{$.BaseURI}}monitor/delete/{{.MonitorID}}">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
</a>
</td>
</tr>
{{end}}
</table>
But it says
Template File Error: template: read.tmpl:27:47: executing "content" at <.Name.DomainName>: can't evaluate field DomainName in type string
How can I achieve that?
The immediate problem in the template is:
<td>{{.Name.DomainName}}</td>
Name is defined as a string
field on the Monitor
type. Being a string, it does not have a sub-field named DomainName
. Hence the error:
can't evaluate field DomainName in type string
Additionally, thedatabase.SQL.Select(&result, "SELECT app_monitor.id, app_monitor.name, app_monitor.status FROM app_monitor LEFT JOIN user ON app_monitor.domain_id = user.domain_id WHERE user.id = ?", userID)
statement in the model package is not retrieving the DomainName. You'll want to select the other model fields that need to be rendered too. Once the SQL is updated appropriately the following snippet should render the desired output:
<td>{{.Name}}</td>
<td>{{.DomainName}}</td>