global javascript file and handlebar helpers
-
I thank you for your patience as I work through my issues! The quick responses are greatly appreciated!
I saw the part on global
Global scripts - You can set up a script to run for every single template by adding flag isGlobal. This can be done for example in jsreport studio script's properties. Global script can be useful for common tasks like adding common helpers or settings to templates.
but that didn't help me. What do I need to do to set a .js file, or any file, global? Do I need to add the isGlobal to the config.json file? Then how do I do that for a template's helper.js file?
The reason I'm doing this is I want to add a handlebar helper, compare.
This is my helper.js file with the template:
var handlebars = require('handlebars');
var helpers = require('handlebars-helpers')({
handlebars: handlebars
});
var math = helpers.math;handlebars.registerHelper('ifvalue', function (conditional, options) {
if (options.hash.value === conditional) {
return options.fn(this)
} else {
return options.inverse(this);
}
});handlebars.registerHelper('compare', function(lvalue, rvalue, options) {
if (arguments.length < 3) throw new Error("Handlerbars Helper 'compare' needs 2 parameters"); var operator = options.hash.operator || "=="; var operators = { '==': function(l,r) { return l == r; }, '===': function(l,r) { return l === r; }, '!=': function(l,r) { return l != r; }, '<': function(l,r) { return l < r; }, '>': function(l,r) { return l > r; }, '<=': function(l,r) { return l <= r; }, '>=': function(l,r) { return l >= r; }, 'typeof': function(l,r) { return typeof l == r; } } if (!operators[operator]) throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator); var result = operators[operator](lvalue,rvalue); if( result ) { return options.fn(this); } else { return options.inverse(this); }
});
But I get the error that the helper compare is missing. What am I doing wrong now?
Again, thanks for all of the help.
edg
-
hi! Global scripts are something different from what it seems like you are trying to do. what you really want is global helpers, you can create a global helper using jsreport studio ui in the assets section, just go to the assets, create one, and then make sure to check the "shared helpers attached to each template" option.
then just put any helper that you want global in the asset content.
example:
var handlebars = require('handlebars'); var helpers = require('handlebars-helpers')({ handlebars: handlebars }); function toJSON (data) { return JSON.stringify(data); } function ifvalue (conditional, options) { if (options.hash.value === conditional) { return options.fn(this) } else { return options.inverse(this); } } function compare (lvalue, rvalue, options) { if (arguments.length < 3) throw new Error("Handlerbars Helper 'compare' needs 2 parameters"); var operator = options.hash.operator || "=="; var operators = { '==': function(l,r) { return l == r; }, '===': function(l,r) { return l === r; }, '!=': function(l,r) { return l != r; }, '<': function(l,r) { return l < r; }, '>': function(l,r) { return l > r; }, '<=': function(l,r) { return l <= r; }, '>=': function(l,r) { return l >= r; }, 'typeof': function(l,r) { return typeof l == r; } } if (!operators[operator]) throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator); var result = operators[operator](lvalue,rvalue); if( result ) { return options.fn(this); } else { return options.inverse(this); } }
-
PD: when defining helpers in jsreport you can omit the
handlebars.registerHelper(
call, jsreport will register any function that you have in the file as a helper
-
Thanks! That got it working for me. And thanks for the quick replies! I appreciate it!
edg
-
And now I'm having issues and I don't know why.
Got the pdf header to work. In the header, I used a function from the global helper. No problem, it works.
When I assign that header using pdf-utils then the main template complains that it can't find the function. But the function is global? Not sure what is happening with that.
Thanks again for all the help!
edg
-
hi! so far i'm testing using a global helper in both a main template and a header (in the context of pdf-utils) and the global helpers works normally -> https://playground.jsreport.net/studio/workspace/rysEZgTrf/20
can you try to tweak this base workspace https://playground.jsreport.net/studio/workspace/rysEZgTrf/9 do some changes according to what you are trying to do, save it when you are done, and paste the new url back here? with that i will be able to see what is going on in your case.
-
Thanks for the help!
I think this is another local environment issue for me. You have it setup just the way I do and yet it works in the playground here but not locally for me.
https://playground.jsreport.net/studio/workspace/rysEZgTrf/29
I put that data and the files into my system and it fails. My debug data is below.
If I just run the header, it works. If I run the body with no pdf-utils header, it works. As soon as I add that Test Header to the TestingBody, it doesn't work in my environment but does in the playground for me.
Again, any thoughts would be helpful.
Let me know if you need anything else from me.
Thanks!
edg
debug:
Error occured - Error during rendering report: Error during rendering report: Missing helper: "toJSON"
logs (child request):
+0 Starting rendering request 592
+0 Rendering template {shortid:HJ9CayarM, recipe:chrome-pdf,engine:handlebars}
+1 Data item not defined for this template.
+2 Resources not defined for this template.
+3 Base url not specified, skipping its injection.
+3 Rendering engine handlebars
+209 Compiled template not found in the cache, compiling
+216 Replaced images []
+217 Executing recipe chrome-pdf
+418 Running chrome with params {"scale":null,"margin":{}}
+739 Running pdf operation merge
+741 Starting rendering request 593
+742 Rendering template {shortid:BJfYAo2Hf, recipe:chrome-pdf,engine:handlebars}
+743 Inline data specified.
+743 Resources not defined for this template.
+744 Base url not specified, skipping its injection.
+744 Rendering engine handlebars
logs:
+0 Starting rendering request 592
+0 Rendering template {shortid:HJ9CayarM, recipe:chrome-pdf,engine:handlebars}
+1 Data item not defined for this template.
+2 Resources not defined for this template.
+3 Base url not specified, skipping its injection.
+3 Rendering engine handlebars
+209 Compiled template not found in the cache, compiling
+216 Replaced images []
+217 Executing recipe chrome-pdf
+418 Running chrome with params {"scale":null,"margin":{}}
+739 Running pdf operation merge
+741 Starting rendering request 593
+742 Rendering template {shortid:BJfYAo2Hf, recipe:chrome-pdf,engine:handlebars}
+743 Inline data specified.
+743 Resources not defined for this template.
+744 Base url not specified, skipping its injection.
+744 Rendering engine handlebars
+957 Error when processing render request Error during rendering report: Missing helper: "toJSON"
logs (child request):
+0 Starting rendering request 592
+0 Rendering template {shortid:HJ9CayarM, recipe:chrome-pdf,engine:handlebars}
+1 Data item not defined for this template.
+2 Resources not defined for this template.
+3 Base url not specified, skipping its injection.
+3 Rendering engine handlebars
+209 Compiled template not found in the cache, compiling
+216 Replaced images []
+217 Executing recipe chrome-pdf
+418 Running chrome with params {"scale":null,"margin":{}}
+739 Running pdf operation merge
+741 Starting rendering request 593
+742 Rendering template {shortid:BJfYAo2Hf, recipe:chrome-pdf,engine:handlebars}
+743 Inline data specified.
+743 Resources not defined for this template.
+744 Base url not specified, skipping its injection.
+744 Rendering engine handlebars C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19
throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
^Error: Missing helper: "toJSON"
at Object.<anonymous> (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19:13)
at Object.eval [as main] (eval at createFunctionContext (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:254:23), <anonymous>:10:70)
at main (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\runtime.js:173:32)
at ret (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\runtime.js:176:12)
at ret (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\compiler\compiler.js:525:21)
at C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\lib\handlebarsEngine.js:25:14
at evalmachine.<anonymous>:1:41
at ContextifyScript.Script.runInContext (vm.js:59:29)
at ContextifyScript.Script.runInNewContext (vm.js:65:15)
at Object.runInNewContext (vm.js:135:38)
Stak - C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19
throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
^Error: Missing helper: "toJSON"
at Object.<anonymous> (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\helpers\helper-missing.js:19:13)
at Object.eval [as main] (eval at createFunctionContext (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\compiler\javascript-compiler.js:254:23), <anonymous>:10:70)
at main (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\runtime.js:173:32)
at ret (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\runtime.js:176:12)
at ret (C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\node_modules\handlebars\dist\cjs\handlebars\compiler\compiler.js:525:21)
at C:\dev\src\Apps\JsReports\node_modules\jsreport-handlebars\lib\handlebarsEngine.js:25:14
at evalmachine.<anonymous>:1:41
at ContextifyScript.Script.runInContext (vm.js:59:29)
at ContextifyScript.Script.runInNewContext (vm.js:65:15)
at Object.runInNewContext (vm.js:135:38)
-
hi! i don't have a good idea about what is happening in your installation, can you please post here the configuration file (
jsreport.config.json
) that your jsreport server is using? and also can you export your templates and other files that you are using for the test and send me the generated zip file at bjrmatos@gmail.com? that will be helpful to review it and test it in a windows machine.
-
The problem here is that global shared assets were not propagated to the pdf utils rendering requests. This is a bug which is now fixed in jsreport-assets@0.7.1
Please update the package, try again an let us know. Thank you.
-
I saw this and was excited for the fix. However, it appears I'm already at 7.1. Any other thoughts?
-
Are you sure? Can you check you have there this change?
-
If yes, please email me or @bjrmatos the export zip if it is possible.
-
Okay, I was going merely by the .1.0 versions I saw and I had the latest one. I updated but now I get a different error.
I can get my report header to work but the main report won't work now and it used to run on its own.
Error occured - Error during rendering report: Unexpected token } in JSON at position 2144
Stak - SyntaxError: Unexpected token } in JSON at position 2144
at JSON.parse (<anonymous>)
at C:\dev\src\apps\JsReports\node_modules\jsreport-resources\lib\resources.js:37:21
at Array.forEach (<anonymous>)
at C:\dev\src\apps\JsReports\node_modules\jsreport-resources\lib\resources.js:36:15
at tryCatcher (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:512:31)
at Promise._settlePromise (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:569:18)
at Promise._settlePromise0 (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:693:18)
at Promise._fulfill (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:638:18)
at PromiseArray._resolve (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise_array.js:126:19)
at PromiseArray._promiseFulfilled (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise_array.js:144:14)
at Promise._settlePromise (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:574:26)
at Promise._settlePromise0 (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\promise.js:693:18)
at Async._drainQueue (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\async.js:133:16)
at Async._drainQueues (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\async.js:143:10)
at Immediate.Async.drainQueues (C:\dev\src\apps\JsReports\node_modules\bluebird\js\release\async.js:17:14)
at runCallback (timers.js:789:20)
at tryOnImmediate (timers.js:751:5)
at processImmediate [as _immediateCallback] (timers.js:722:5)
-
It seems you have resources associated with the template, but one of the resources include invalid json.
-
yep. I r dummy. I will fix and let you know. Sorry about that. Thanks for all your help!
-
Okay, yes to the dumb resource issue. Also, the new version of js-assets fixed the global.js issue I was having.
Again, my thanks for all your help!
edg
-
Rather than make a new topic, again, I will ask a semi-related question here.
Is there a way to access the localizedResource in the global javascript file? Or do I have to do some init() type initialization? My intent is to make localization easier in the scripts for others who read it. This would allow me to parse the localization file out to the parts we create with better names.
I guess that brings up, I know there is beforeRender, is there an initialize event to do this?
Thanks!
edg
-
What you you mean with "global javascript file"? I'm not sure I get your intentions.
-
I have a js file marked as "shared helpers attached to each template." That allows me to use any functions I create across all the templates.
Is there an onInit() or similar call I can do so I can pass my localizations ($localizedResource) and have them available in some global variable I set? This is going to allow me to create functions with parameters like getDataColumnName(database, column, value) instead of needing to know the localizedResource file?
I do read the examples and items on the learn page but it's not clicking with me how I could do this or if it's even possible. I wish I could understand why!
Thanks!
edg
-
This is a bit hack. But does it help to reach your goal?
https://playground.jsreport.net/studio/workspace/VkLWfMyMb/120Basically the shared helpers doesn't have an event like onInit. It is just evaluated before templating engine runs. You can use any global code to do the init like recalculating the inputs.
-
Thanks! I think the "this.m.data.$localizedResource" was the main thing I was wanting.
I appreciate it!
edg