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 }}
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.