Home > Blockchain >  Go 1.19 Error executing template: {{range}} branches end in different contexts: extra javascript lin
Go 1.19 Error executing template: {{range}} branches end in different contexts: extra javascript lin

Time:09-11

Please find example in Go Playground. Comment (//) the line onRuleAreaChange(document.getElementById('ruleArea0')); to see the problem

I have some JavaScript that changes drop-down (SELECT) lists on forms based upon other drop-down list selections. To initialise the drop-down lists I call the onChange function I have written. On initialisation of the form, I call the onChange function for each row of my form.

The following lines of code range over each row and makes the call for that row thus setting up the configuration of the other fields in the whole row.

        // Initialise all the rows
    {{- range $i,$v  := .}}
    onRuleAreaChange(document.getElementById('ruleArea{{$i}}'));
    {{- end}}

Go tells me that I have a {{range}} ending in different contexts, I'm not sure why - I looked all over the place for some missing terminator.

The fix for this was to simply add a line that is identical to the first line generated in the range loop. i.e. initialise the first row (which I always have) before ranging over the whole set as follow:

       // Initialise all the rows
    onRuleAreaChange(document.getElementById('ruleArea0'));
    {{- range $i,$v  := .}}
    onRuleAreaChange(document.getElementById('ruleArea{{$i}}'));
    {{- end}}

Can someone see why adding this extra line resolves the problem?

The final output that works is:

    onRuleAreaChange(document.getElementById('ruleArea0'));
    onRuleAreaChange(document.getElementById('ruleArea0'));
    onRuleAreaChange(document.getElementById('ruleArea1'));

The output I would like to get but can't because of the error is:

    onRuleAreaChange(document.getElementById('ruleArea0'));
    onRuleAreaChange(document.getElementById('ruleArea1'));

CodePudding user response:

From the docs:

ErrBranchEnd: "{{if}} branches end in different contexts"
Example:
{{if .C}}<a href="{{end}}{{.X}}
Discussion:
Package html/template statically examines each path through an {{if}}, {{range}}, or {{with}} to escape any following pipelines.
The example is ambiguous since {{.X}} might be an HTML text node, or a URL prefix in an HTML attribute. The context of {{.X}} is used to figure out how to escape it, but that context depends on the run-time value of {{.C}} which is not statically known.

The problem is usually something like missing quotes or angle brackets, or can be avoided by refactoring to put the two contexts into different branches of an if, range or with. If the problem is in a {{range}} over a collection that should never be empty, adding a dummy {{else}} can help.

When you run your example the full error is :

html/template:test:30:18: {{range}} branches end in different contexts: {stateJS delimNone urlPartNone jsCtxRegexp attrNone elementScript <nil>}, {stateJSLineCmt delimNone urlPartNone jsCtxRegexp attrNone elementScript <nil>}

So the differing contexts mentioned above are stateJS and stateJSLineCmt; the error is because if the range outputs something then the context is "javascript" otherwise it`s "Javascript Line Comment" (i.e. a continuation of the comment above). Not sure if that really explains it well but, fortunately, it's easily solved:

// Now initialise all the rows
/* onRuleAreaChange(document.getElementById('ruleArea0')); */
{{- range $i,$v  := .}}
onRuleAreaChange(document.getElementById('ruleArea{{$i}}'));
{{- end}}

Will work as expected playground as will the following playground:

// Now initialise all the rows
// onRuleAreaChange(document.getElementById('ruleArea0')); 
{{- range $i,$v  := .}}
onRuleAreaChange(document.getElementById('ruleArea{{$i}}'));
{{else}}
;
{{- end}}

CodePudding user response:

Go is making the assumption that the generated code is not part of the comment. I'm not completely convinced that it should do this because I do have generated comments in GO templates.

By removing the - from the {{- range the error doesn't happen

  • Related