Storing temporary values during report rendering
-
In large reports I often have the need to reuse a calculated value. I don't thinks it's much of a performance gain, but I think the code gets a bit cleaner. I tried to find a standard way of storing such values, but there doesn't seem to be any in Handlebars nor in jsreport.
It's easy enough to fix this with two functions. For now I store the values in
options.data.root._tempVar
. This should be safe for my use. I'm pretty sure that I won't send a data object with a _tempVar field to jsreport.- Is this what I have to do to get this feature?
- Should I do it in an other way?
- Is there anything in jsreport that already provides this functionality?
<!--Example usage--> <!--getTypeCount sets a filter on the things array and returns the number of elements--> {{setVar type1Count things (getTypeCount 1)}} {{setVar type2Count things (getTypeCount 2)}} There are {{getVar type1Count}} things of type 1. There are {{getVar type2Count}} things of type 2. <!--This section is only visible if there are more than 0 things of type 1--> {{#compare type1Count '>' 0}} {{#each (getThings 1)}} <!--A list of each thing of type 1--> {{/each}} {{/compare}}
//Helper functions function setVar(varName, varValue, options) { if (!options.data.root) options.data.root = {}; if(!options.data.root._tempVar) options.data.root._tempVar = {}; options.data.root._tempVar[varName] = varValue; }; function getVar(varName, options) { if (!options.data.root || !options.data.root._tempVar) return null; return options.data.root._tempVar[varName]; };
-
In case you need to reuse some data just between helpers, you can also use root scope.
let someReusedData = 1 function helperA() { someReusedData++ } function helperB() { return someReusedData }
In case you want to reuse data between child templates and scripts, you should use the approach with passing shared data through request
data
prop.
-
Ok, thanks.
I'm currently decomposing my reports into child reports. I.e .I will be needing access to options.data from everywhere.
-
Note that helpers can't modify the input
req.data
for the other processing like child templates or scripts. It is just local for particular helpers evaluation.
You need to use jsreport script if you want to modify it.
-
Aha, great info. I thought that child templates had access to
this
, which also would include my updated options.data.root.So I'll have to marshal all the data through parameters in the #child command then?
Btw, the jsreport (or Handlebars) is really picky with parsing the #child command. Here is a real life example:
<!--working--> {#child blueprint_with_controlpoint @data.drawing$={{{childTemplateSerializeData ../this}}} @data.controlpoint$={{{childTemplateSerializeData ./this}}} @data.size=15 } <!--working--> {#child blueprint_with_controlpoint @data.drawing$={{{childTemplateSerializeData ../this}}} @data.controlpoint$={{{childTemplateSerializeData ./this}}} @data.size=15 } <!--NOT working - the closing bracket must be preceded with a space --> {#child blueprint_with_controlpoint @data.drawing$={{{childTemplateSerializeData ../this}}} @data.controlpoint$={{{childTemplateSerializeData ./this}}} @data.size=15} <!--NOT working - the closing bracket cannot be on separate line - the first parameter must be on the first line --> {#child blueprint_with_controlpoint @data.drawing$={{{childTemplateSerializeData ../this}}} @data.controlpoint$={{{childTemplateSerializeData ./this}}} @data.size=15 }
-
So I'll have to marshal all the data through parameters in the #child command then?
The whole data are always passed to the child templates. You use parameters only if you need to specify some index to the root data or something custom.
Btw, the jsreport (or Handlebars) is really picky with parsing the #child command. Here is a real life example:
I believe this was fixed here. The fix will be part of the next release.
-
I'm sorry, but you lost me. I must have misunderstood your previous post.
"Note that helpers can't modify the input req.data for the other processing like child templates or scripts"Question: If I add data to
options.data.root
(as per the code above) from within my main template with the help from a helper function, will a child template get access to this updated data in "root"?