Reputation: 4705
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
Reputation: 418107
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.)
printf
and %T
verbWe 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