Is there a better way where I can check if a template property was not resolved?

Issue

I am trying to build a string using text/template, where the template string could have arbitrary properties that are resolved via a map.

What I am trying to accomplish is identifying where one/any of the template properties is not resolved and return an error.

At the moment, I am using regexp but reaching out to the community of see if there was a better solution.

package main

import (
    "bytes"
    "fmt"
    "regexp"
    "text/template"
)

func main() {
    data := "teststring/{{.someData}}/{{.notExist}}/{{.another}}"
    // the issue here is that data can be arbitrary so i cannot do
    // a lot of unknown if statements

    t := template.Must(template.New("").Parse(data))
    var b bytes.Buffer

    fillers := map[string]interface{}{
        "someData": "123",
        "another":  true,
        // in this case, notExist is not defined, so the template will
        // note resolve it
    }
    if err := t.Execute(&b, fillers); err != nil {
        panic(err)
    }

    fmt.Println(b.String())
    // teststring/123/<no value>/true
    // here i am trying to catch if a the template required a value that was not provided
    hasResolved := regexp.MustCompile(`<no value>`)
    fmt.Println(hasResolved.MatchString(b.String()))

    // add notExist to the fillers map
    fillers["notExist"] = "testdata"
    b.Reset()
    if err := t.Execute(&b, fillers); err != nil {
        panic(err)
    }
    fmt.Println(b.String())
    fmt.Println(hasResolved.MatchString(b.String()))

    // Output:
    // teststring/123/<no value>/true
    // true
    // teststring/123/testdata/true
    // false
}

Solution

You can let it fail by settings the options on the template:

func (t *Template) Option(opt ...string) *Template
"missingkey=default" or "missingkey=invalid"
    The default behavior: Do nothing and continue execution.
    If printed, the result of the index operation is the string
    "<no value>".
"missingkey=zero"
    The operation returns the zero value for the map type's element.
"missingkey=error"
    Execution stops immediately with an error.

If you set it to missingkey=error, you get what what want.

t = t.Options("missingkey=error")

Answered By – The Fool

Answer Checked By – Senaida (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.