Siya Mzam
Siya Mzam

Reputation: 4705

How to test if a value is a string in a template

I would like to find out if it is possible and if so how, to test if a value is a string in a Go template.

I have tried the following with no success

{{- range .Table.PrimaryKeys.DBNames.Sorted }}{{ with (index $colsByName .)}}
{{ .Name }}: {{ if .IsArray }}[]{{ end }}'{{.Type}}', {{end}}
{{- end }}
{{- range $nonPKDBNames }}{{ with (index $colsByName .) }}
    {{ .Name }}: {{ if .IsArray }}[]{{end -}} {
  type: {{ if .Type IsString}}GraphQLString{{end -}}, # line of interest where Type is a value that could be a number, string or an array
}, {{end}}
{{- end }}

And this is the error that I get

Error: error parsing TablePaths: error parsing contents template: template: templates/table.gotmpl:42: function "IsString" not defined

Upvotes: 5

Views: 5082

Answers (1)

icza
icza

Reputation: 418107

With a custom function

There is no predeclared IsString() function available in templates, but we may easily register and use such a function:

t := template.Must(template.New("").Funcs(template.FuncMap{
    "IsString": func(i interface{}) bool {
        _, ok := i.(string)
        return ok
    },
}).Parse(`{{.}} {{if IsString .}}is a string{{else}}is not a string{{end}}`))
fmt.Println(t.Execute(os.Stdout, "hi"))
fmt.Println(t.Execute(os.Stdout, 23))

This will output (try it on the Go Playground):

hi is a string<nil>
23 is not a string<nil>

(The <nil> literals at the end of lines are the error values returned by the template execution, telling there were no errors.)

Using printf and %T verb

We may also do this without custom functions. There is a printf function available by default, which is an alias for fmt.Sprintf(). And there is a %T verb which outputs the argument's type.

The idea is to call printf %T on the value, and compare the result with "string", and we're done:

t := template.Must(template.New("").
    Parse(`{{.}} {{if eq "string" (printf "%T" .)}}is a string{{else}}is not a string{{end}}`))
fmt.Println(t.Execute(os.Stdout, "hi"))
fmt.Println(t.Execute(os.Stdout, 23))

This will also output (try it on the Go Playground):

hi is a string<nil>
23 is not a string<nil>

Upvotes: 5

Related Questions