Form Always Empty - go

I've been building a Go todo list and I'm trying to add the ability to add new items, but every time I access the form value, it comes out empty. Here's the handler I built:
func addHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
fmt.Print(err)
}
cook, _ := r.Cookie("userid")
id := cook.Value
r.ParseForm()
text := r.FormValue("todo")
addTodo(text,id) //inserts into database
http.Redirect(w,r,"/todo",http.StatusFound)
}
And here's the html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
{{range .}}
<tr><td>{{printf "%s" .Text}}</td><td>delete</td></tr>
{{end}}
</table>
<form action="/add" method="post"><input type="text" name="todo"><button type="submit">Add</button></form>
</body>
</html>

Related

How to Golang loop in html with http/template and net/http?

I am trying to handle data and then send it into html to be displayed in a specific field.
No expected output into {{.name}}. Works fine with {{.}}. No known structural wrongdoing.
Golang code
package main
import (
"fmt"
"html/template"
"net/http"
"github.com/gorilla/context"
)
var tpl *template.Template
func main() {
tpl, _ = template.ParseGlob("*.html")
http.HandleFunc("/test", testHandler)
http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
}
type Data struct {
allData []string
}
func testHandler(w http.ResponseWriter, r *http.Request) {
data := Data{allData: []string{"Add new", "jeff", "ffeej"}}
tpl.ExecuteTemplate(w, "test.html", data)
}
HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
</head>
<body>
<section>
{{range .allData}}
{{.}}
{{end}}
</section>
</body>
</html>
How does one get the data out of the handler into the html in a specific wanted field?
What am I missing? I am still learning golang.
Thanks in advance.

Prevent overwriting of blocks with same name in Go Template

I'm having difficulty in rendering the correct content using templates in Go. Either case of navigating to /about or / the same content is getting rendered. Below is the current state of code.
I have read that you can parse templates in each handleFunc (for each request) but that seems to be an inefficient way to mitigate the issue.
Code
I have the following templates
base
header
footer
index
about
{{ define "base"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Project Website</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css#2/out/water.css">
</head>
<body>
{{template "header" .}}
{{template "body" .}}
{{template "footer" .}}
</body>
</html>
{{end}}
{{define "header"}}
<h1>Header</h1>
{{end}}
{{define "footer"}}
<h1>Footer</h1>
{{end}}
{{template "base" .}}
{{define "body"}}
<h1>About</h1>
{{end}}
{{template "base" .}}
{{define "body"}}
<h1>Index</h1>
{{end}}
main.go
package main
import (
"html/template"
"log"
"net/http"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*"))
}
func main() {
// Connect to database.
// Routes
http.HandleFunc("/about", about)
http.HandleFunc("/", index)
http.HandleFunc("/favicon.ico", doNothing) // TODO Replace with something like do not found
// Listen and serve.
log.Fatal(http.ListenAndServe(":8000", nil))
}
// TODO go away
func doNothing(w http.ResponseWriter, r *http.Request) {}
handlerFunctions.go
package main
import (
"log"
"net/http"
)
func index(rw http.ResponseWriter, req *http.Request) {
log.Println("Index page called")
tpl.ExecuteTemplate(rw, "index.gohtml", nil)
}
func about(rw http.ResponseWriter, req *http.Request) {
log.Println("About page called")
tpl.ExecuteTemplate(rw, "about.gohtml", nil)
}

How to stream a PDF

I use Go and Gin for handle my web service. I want to stream a PDF file.
I tried to use html embed tag and pdf url for tag src, but this method not help me, because browser download the pdf.
For pdf handler I set content-type and someother headers but not work.
GO
func DownloadPdf(c *gin.Context) {
c.Writer.Header().Set("Content-type", "application/pdf")
c.FileAttachment(fmt.Sprintf("%s/order_%v.pdf", fileBasePath, myOrderUrl.OrderId), "bilit_pdf.pdf")
}
func LoadHtml(c *gin.Context) {
t, err := template.ParseFiles("Modules/Pdf/templates/pdf.gohtml")
if err != nil {
panic(err)
}
buf := new(bytes.Buffer)
if err = t.Execute(buf, "http://localhost:3001/v2/pdf/download/YfTgLuPPDc"); err != nil {
panic(err)
}
if _,err:=buf.WriteTo(c.Writer);err!=nil{
panic(err)
}
}
HTLM
<!DOCTYPE html>
<html lang="en" style="height: 100%;width: 100%">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100%;width: 100%;margin: 0;overflow:hidden">
<embed
src="{{.}}"
type="application/pdf"
frameBorder="0"
height="100%"
width="100%">
</embed>
</body>
</html>
I found the answer with adding
c.Writer.Header().Set("Content-type", "application/octet-stream")
into my download code .
and opened PDF file when DownloadPdf route called .

Why does this request not POST?

There are many similar questions implemented in different stacks, but I have not found a useful answer. This code is modeled on many different tutorials, here is one: https://divyanshushekhar.com/golang-forms-data-request-body/
Pressing the button is supposed to submit the form so that the value of dataRequest can be used, however, it does not appear to post. Why?
<!DOCTYPE html>
<meta charset="utf-8" http-equiv="Content-Security-Policy" content="img-src * 'self' data: https:">
<head>
<title>Demo</title>
<link rel="icon" type="image/png" href="./favicon.ico">
</head>
<body style="background-color:#F0F8FF" style="font-size: 18px; font-family:verdana,arial,tahoma,serif;">
<form name="demoForm" style="background-color:#92a8d1">
<fieldset>
<input id="dataRequest" type="request" method="POST" value=""/>
<button type="submit" value="Run" />
</fieldset>
</form>
</body>
</html>
package main
import (
"fmt"
"net/http"
"log"
)
func index() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
http.ServeFile(w, r, "visible/index.html")
return
case "POST":
fmt.Println("Posted a request!")
err := r.ParseForm();
if err != nil {
log.Fatal(err)
}
request := r.Form.Get("dataRequest")
fmt.Println(request)
return
}
})
}
func main() {
mux := http.NewServeMux()
mux.Handle("/", index())
http.ListenAndServeTLS(":443", "./server.crt", "./server.key", mux)
}

ExecuteTemplate (template.ParseGlob) loads Blank page

I'm trying to load template page.gohtml from folder cms/template. When trying to view in Firefox browser it load Blank.
handler.go file
var Tmpl = template.Must(template.ParseGlob("../templates/*"))
func ServeIndex(w http.ResponseWriter, r *http.Request) {
p := &Page{
Title: "Go Projects CMS",
Content: "Welcome to the Home Page!",
Posts: []*Post{
{
Title: "Hello World!",
Content: "Hey y'all, Thanks for coming",
DatePublished: time.Now(),
},
{
Title: "This Has Comments",
Content: "Atlassian Just Bought Trello...GO!",
DatePublished: time.Now().Add(-time.Hour),
Comments: []*Comment{
{
Author: "Davy Jones",
Content: "This is something to say about something",
DatePublished: time.Now().Add(-time.Hour / 2),
},
},
},
},
}
Tmpl.ExecuteTemplate(w, "page", p)
}
cmd/main.go file
func main() {
r := mux.NewRouter()
r.HandleFunc("/", cms.ServeIndex)
fmt.Println("Server running at port 3000")
go http.ListenAndServe(":3000", r)
fmt.Scanln()
}
templates/page.gohtml
{{ define "page" }}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ .Title }}</title>
<link rel="stylesheet" href="https://unpkg.com/tachyons#4.10.0/css/tachyons.min.css"/>
</head>
<body class="w-100 sans-serif bg-white">
<h1>Welcome</h1>
<div class="baskerville pb5">
{{ .Content }}
{{if .Posts}}
{{range .Posts}}
{{template "post" .}}
{{end}}
{{end}}
</div>
</body>
</html>
{{ end }}
I found the issue when I used error handling.
if err := Tmpl.ExecuteTemplate(w, "page", p); err != nil {
log.Printf("Template error: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
Which printed "no such template comments" while I was using defined "comment" inside comment.gohtml
Sorry for posting this question, I recently started GoLang.

Resources