Combining two if conditions into one

4/1/2019

The below works

{{- if hasKey (index $envAll.Values.policy) "type" }} 
{{- if has "two-wheeler" (index $envAll.Values.policy "type") }}
<code goes here>
{{- end }}
{{- end }}

while the below fails with "runtime error: invalid memory address or nil pointer dereference"

{{- if and (hasKey (index $envAll.Values.policy) "type") (has "two-wheeler" (index $envAll.Values.policy "type")) }}
<code goes here>
{{- end}}

There is no list by name "type" declared under $envAll.Values.policy.

In Go, if the right operand is evaluated conditionally, why does the last condition gets evaluated in the second code snippet? How do I solve it?

Edit (since it marked as duplicate): Unfortunately, I cannot use embedded {{ if }} like it is mentioned in the other post.

I simplified my problem above. I actually have to achieve this...

{{if or (and (condition A) (condition B)) (condition C)) }}
    <code goes here>
{{ end }}
-- Hem
go
go-templates
kubernetes-helm
sprig-template-functions

1 Answer

4/2/2019

You get an error when using the and function because the and function in Go templates is not short-circuit evaluated (unlike the && operator in Go), all its arguments are evaluated always. Read more about it here: Golang template and testing for Valid fields

So you have to use embedded {{if}} actions so the 2nd argument is only evaluated if the first is also true.

You edited the question and stated that your actual problem is this:

{{if or (and (condition A) (condition B)) (condition C)) }}
    <code goes here>
{{ end }}

This is how you can do it in templates only:

{{ $result := false }}
{{ if (conddition A )}}
    {{ if (condition B) }}
        {{ $result = true }}
    {{ end }}
{{ end }}
{{ if or $result (condition C) }}
    <code goes here>
{{ end }}

Another option is to pass the result of that logic to the template as a parameter.

If you can't or don't know the result before calling the template, yet another option is to register a custom function, and call this custom function from the template, and you can do short-circuit evaluation in Go code. For an example, see How to calculate something in html/template.

-- icza
Source: StackOverflow