Check if item exist and is true or false

in my code I’m sending a struct ReturnedResult to the template:

type ReturnedResult struct {
	Result  bool   `json:"result"`
	Message string `json:"message"`
}

I want the template to:

  1. Check if there is a Result or nil
  2. If there is a Result I want to check if it is true or false

So, i wrote the below:

{{with .Result}}
  {{if .Result}}
    <div id='foo'>
      <i class="far fa-thumbs-up"></i>If report not opened automatically, pls download from <a href={{.Message}}>here</a>
    </div>
    <script>
      url = `{{.Message}}`
      window.open(url, "_blank");
      setTimeout(function () {document.querySelector('#foo').style.display='none'}, 5000);
    </script>
  {{else}}
    <i class="fas fa-exclamation-triangle">{{.Message}}</i>>
    <script>
      setTimeout(function () {document.querySelector('#foo').style.display='none'}, 5000);
    </script>
  {{end}}
{{end}}

Sometime I call the template without data as tmpl.Execute(w, nil), some times with data as tmpl.Execute(w, webReturn)

The one without data is working fine, but the one with data is not working and no idea what is wrong.

Below is my full code if required.

// go build -ldflags "-H=windowsgui"
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"text/template"

	"github.com/zserge/lorca"
)

// ContactDetails ...
type ContactDetails struct {
	Email   string
	Subject string
	Message string
	Color1  []string
	Color2  []string
}

// ReturnedResult ...
type ReturnedResult struct {
	Result  bool   `json:"result"`
	Message string `json:"message"`
}

func index(w http.ResponseWriter, r *http.Request) {
	tmpl := template.Must(template.ParseFiles("forms.html"))
	if r.Method != http.MethodPost {
		tmpl.Execute(w, nil)
		return
	}

	r.ParseForm()
	fmt.Println(r.Form) // print information on server side.
	fmt.Println("path", r.URL.Path)
	fmt.Println("scheme", r.URL.Scheme)
	fmt.Println(r.Form["color1"][0])
	fmt.Println(r.Form["color1"][1])
	for k, v := range r.Form {
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v, ""))
	}
	details := ContactDetails{
		Email:   r.FormValue("email"),
		Subject: r.FormValue("subject"),
		Message: r.FormValue("message"),
		Color1:  r.Form["color1"],
		Color2:  r.Form["color2"],
	}
	fmt.Printf("Post from website! r.PostFrom = %v\n", r.PostForm)
	fmt.Printf("Details = %v\n", details)

	//r.FormValue("username")
	fmt.Println()
	// do something with details
	sheetID := "AKfycbxfMucXOzX15tfU4errRSAa9IzuTRbHzvUdRxzzeYnNA8Ynz8LJuBuaMA/exec"
	url := "https://script.google.com/macros/s/" + sheetID + "/exec"
	bytesRepresentation, err := json.Marshal(details)
	if err != nil {
		log.Fatalln(err)
	}
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(bytesRepresentation))
	if err != nil {
		log.Fatalln(err)
	}
	// read all response body
	data, _ := ioutil.ReadAll(resp.Body)

	// close response body
	resp.Body.Close()

	webReturn := ReturnedResult{}
	if err := json.Unmarshal([]byte(data), &webReturn); err != nil {
		panic(err)
	}
	fmt.Println(webReturn.Message)

	webReturn.Message = strings.ReplaceAll(webReturn.Message, "&export=download", "")
	//tmpl.Execute(w, struct{ Success bool }{webReturn.Result})
	tmpl.Execute(w, webReturn)
}

func main() {
	// Start Host goroutine
	go func() {
		http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))
		http.HandleFunc("/", index)
		http.ListenAndServe(":8090", nil)
	}()

	// Start UI
	ui, err := lorca.New("http://localhost:8090/index", "", 1200, 800)
	if err != nil {
		log.Fatal(err)
	}
	defer ui.Close()

	<-ui.Done()
}

Template;

<title>Form Submittal</title>
<style>
  body {
      font-family: Ubuntu, "times new roman", times, roman, serif;
  }
</style>
<link href="http://localhost:8090/static/fontawesome-free-5.15.2-web/css/all.css" rel="stylesheet"> <!--load all styles -->
<!-- link rel="stylesheet" href="http://localhost:8090/styles/MaterialDesign-Webfont-master/css/materialdesignicons.min.css" -->

<script type="module" src="http://localhost:8090/static/node_modules/@mdi/js/mdi.js"></script>
<script type="module">
 // import {mdi-home} from "./node_modules/@mdi/js/mdi.js";
 // alert(a);
</script>
<script>
  //import { mdi-home } from '/MaterialDesign-JS-master/mdi.js';
  function deleteRow(row) {
    var i = row.parentNode.parentNode.rowIndex - 2; // this -> td -> tr // -2 because the first 2 rows are used for header
    var tbl = document.querySelector('tbody');
    if(tbl && tbl.rows.length > 1) {
      tbl.deleteRow(i); 
      Array.from(tbl.rows).forEach((row, index) => {
        row.cells[0].innerHTML = index + 1;
      });
    }
  } 

  function insRow(row) {
    var i = row.parentNode.parentNode.rowIndex - 2; // this -> td -> tr // -2 because the first 2 rows are used for header
    var tbl = document.querySelector('tbody');
    var row = document.createElement('tr');
    row.innerHTML=`
      <th></th>
      <td><input size=25 type="text" name="color1" /></td>
      <td><input size=25 type="text" name="color2" ></td>
      <td><i class="fas fa-edit" onclick="insRow(this)"></i></td>
      <td><i class="fas fa-eraser" onclick="deleteRow(this)"></i></td>
    `;
    var len = tbl.rows.length;
    row.cells[0].innerHTML = len + 1;
    tbl.insertBefore(row, tbl.children[i+1]);
    Array.from(tbl.rows).forEach((row, index) => {
      row.cells[0].innerHTML = index + 1;
    });
    //tbl.appendChild(row);
  }
</script>
<h1>Contact</h1>
Bob lives in a <span class="mdi mdi-home"></span>.

<form method="POST">
    <label>Email:</label><br />
    <input type="text" name="email"><br />
    <label>Subject:</label><br />
    <input type="text" name="subject"><br />
    <label>Message:</label><br />
    <textarea name="message"></textarea><br />

    <table>
      <caption>Monthly savings</caption>
      <thead>
        <tr>
          <th colspan="5">The table header</th>
        </tr>
        <tr>
          <th>SN</td>
          <th>PO number</td>
          <th>PO invoice value</td>
          <th colspan="2">Action</td>
        </tr>
      </thead>
      <tbody >
        <tr>
          <th>1</th>
          <td><input size=25 type="text" name="color1" /></td>
          <td><input size=25 type="text" name="color2" /></td>
          <td colspan="2"><i class="fas fa-edit" onclick="insRow(this)"></i></td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <th colspan="5">The table footer</th>
        </tr>
      </tfoot>
    </table>

   <input type="submit">
</form>
{{with .Message}}
  {{if .Result}}
    <div id='foo'>
      <i class="far fa-thumbs-up"></i>If report not opened automatically, pls download from <a href={{.Message}}>here</a>
    </div>
    <script>
      url = `{{.Message}}`
      window.open(url, "_blank");
      setTimeout(function () {document.querySelector('#foo').style.display='none'}, 5000);
    </script>
  {{else}}
    <i class="fas fa-exclamation-triangle">{{.Message}}</i>>
    <script>
      setTimeout(function () {document.querySelector('#foo').style.display='none'}, 5000);
    </script>
  {{end}}
{{end}}

Result is bool, so it will alway either be true or false, if you want it to be also be “nullable”, you need to make it *bool.

The struct will always have a Result, each attribute will always be available. You may omit the result key from the JSON object, and parsing the JSON will fail if I remember correctly, if you want to make the key optional in the JSON use *bool.

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