Defining Variables in a Golang Template

I would like to use a variable in a Golang HTML template.

I have the following code:

{{$dv := .Direction}}

.Direction contains the correct data but the compiler tells me that "File not Found: searchTicket.html:109 undefined variable “$dv”

I have searched around but not able to see why other examples work but not mine.

The variable $dv is not defined in my .go code. Do I have to add additional HTML tags to my .html file?

Thanks in advance.

With https://play.golang.org/p/8T1achXVkm I can get a similar error:

main.go:18: template: :3: undefined variable "$dv"

by changing

{{$dv := .Direction}}

to

{{$dv = .Direction}}

If this does not fix your problem, please tell us more.

Hi nathankerr, sorry, I messed up the original post. The statement {{$dv := .Direction}} is not the problem. I get the error message "File not Found: searchTicket.html:109 undefined variable “$dv” where I do

{{if eq $dv “Desc” }} It seems that $dv is outside the scope of the code for {{$dv := .Direction}}

Thanks

Could you modify https://play.golang.org/p/1fCnJa9wK4 to reflect your template code and share the result?

I don’t know anything about the code I can’t see or reference line numbers in errors to files I don’t have.

Sorry the delay.Here is my HTML template. I added the two lines of code at (A) and (B) and this got rid f the error message, The values in the table list such as .Main_ticket_nr are displaying properly, The problem stills remains that the variables $dv at © and $cv at (D) are not being assigned. I have checked and the values in the GO code and they are correct. Either “Desc” or “Asc”. What am I doing wrong? many thanks,

<head>
    <meta charset="utf-8">
    <title>Go Ticket Tracking</title>

</head>
<style type="text/css">
......
</style>
<body>
<h1> Go Ticket - Search</h1>
{{$dv:= ""}} <<<< (A)
{{$ca:= ""}} <<<< (B)
<center><form id="searchform" name="searchform" style="width:80%" method="post">
    <table width="100%" border="1" cellpadding="6">

        <tbody>
        <tr>
            <td><label>Search:</label></td>
            <td colspan="4"><input placeholder="Enter search requirements" type="text" name="psummary2" id="psummary2" maxlength="45" tabindex="2"></td><td><div align="right"><button class="searchbutton" type="submit" id="button1" value="some" name="subbutton">Search</button></div></td><td><div align="right"><button class="searchbutton" value="all" type="submit" id="button2" name="subbutton">All</button></div></td>

            </tr>
        <tr>
            <td>Ticket</td>
            <td width="2 cm">Status</td>
            <td width="3 cm">Start Date</td>
            <td>Allocator</td>
            <td>Engineer</td>
            <td>Summary</td>
            <td width="3 cm">End Date</td>
        </tr>


            {{range .}}
        <tr>
            <td><a href="amendTicket?id={{.Main_ticket_nr}}" type="submit" onclick="searchform.action='amend_Ticket.html'; return true;">{{.Main_ticket_nr}}</a></td><td>{{.Status}}</td><td>{{.StartDate}}</td><td>{{.Allocator}}</td><td>{{.Engineer}}</td><td>{{.Summary}}</td><td>{{.EndDate}}</td>
            {{$dv:= .Direction}}
            {{$ca:= .Catagory}}
        </tr>
            {{end}}

            <tr>
              <td><label>Sort by:</label></td>
            <td colspan="4"><select name="sortselect" id="sortselect">
 		....
              </select></td>
            <td><label>Direction:</label></td>
            <td><select name="directionselect" id="directionselect">
                {{if eq $dv "Desc"}}<option value="Desc" selected>Descending</option>{{else}}<option value="Desc">Descending</option>{{end}} <<<< (C)
                {{if eq $dv "Asc"}}<option value="Asc" selected>Ascending</option>{{else}}<option value="Asc">Ascending</option>{{end}} <<<< (D)
            </select></td>
        </tr>
        </tbody>
    </table>
    <div align="right">
      <button class="cancelbutton" type="button" onclick="window.location.href='/index'">Cancel</button>
    </div>

    <input type="hidden" name="mode" value="1">
</form></center>

</script>
</body>
</html>

Variables in text/template and html/template aren’t really variables. They are more like immutable bindings that can be shadowed by new declarations.

In this case, the assignment:

{{$dv:= .Direction}}

is inside a range/end block. That $dv only exists until the end of the loop {{end}}, at which point $dv reverts to its previous definition at (A).

It seems you want $dv at © to be the Direction of the last of the list of input values to the template (i.e, .). Since the template packages are designed to discourage including business logic in the template, they don’t support arithmetic, which makes getting that value more difficult. If the first Direction is acceptable, it can be gotten with {{(index . 0).Direction}}.

If you must use the last Direction value, I thought of three methods:

  1. include a method that does integer subtraction in the template’s FuncMap, then do something like {{(index . (subtract (len .) 1).Direction}}

  2. Wrap the list you pass in (referred to as .) in a struct that includes the calculated direction, then get it with something like {{.Direction}}

  3. Add a member function to the data type you pass into the template that calculates the direction. You might need to name the type first: For example:

     type mytypes []mytype
     func (mt mytypes) Direction() string {
         return mt[len(mt)-1].Direction    
     }
    

    making sure you are passing a mytypes into the template, and then get the direction with {{.Direction}}

From what I can see of the template, I would choose method 3.

Also, you can reduce

 {{if eq $dv "Desc"}}<option value="Desc" selected>Descending</option>{{else}}<option value="Desc">Descending</option>{{end}}

to

 <option value="Desc"{{if eq $dv "Desc"}}selected{{end}}>Descending</option>

Thanks nathankerr, until I read your latest reply, I had never really understood how embedded code in templates and Golang really worked together. I have used the {{(index . (subtract (len .) 1).Direction}} option but I will revisit this problem to see how the other options work.

1 Like

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