Reputation: 599
I'm generating a handlebars view for express js framework, and I need to access the variables I pass to the view from inside a separate JavaScript file.
For example:
var foo = {{user.name}}
Someone got an idea? Helper?
Upvotes: 19
Views: 29391
Reputation: 682
Save as helper:
json: function (n: any) {
return JSON.stringify(n)
},
Send:
<script src="/path/to/src" data="{{json data}}"></script>
Get:
const data= JSON.parse(document.body.querySelector('script[data]').getAttribute('data'))
Upvotes: 1
Reputation: 31
var pageData = "{{pageData}}";
pageData = pageData.replace(/"/g, `"`);
pageData = JSON.parse(pageData)
where pageData is an object (that may hold other objects)
Upvotes: 0
Reputation: 21
I didn't know how to do this in a separate js file either. These answers led me in the right direction, so thank you! I ended up JSON stringifying the data on the server-side, before I passed it to the page via render. However, I still couldn't get the code to work in a separate js file - which is fine. My use case was for Materialize input form autocomplete.
// code is inside of a router.get block, therefore access to the response(res)
let customerData = {}
// add customer data with a loop, or whatever
const customers = JSON.stringify(customerData)
res.render('path/to/page', {
customers
})
// code placed within script tags of the handlebars file, not a separate js file
const customers = {{{customers}}}
Upvotes: 2
Reputation: 9822
Node can pass encoded JSON to the handlebars-view like this:
result.render('index', {
encodedJson : encodeURIComponent(JSON.stringify(jsonData))
});
The handlebars-view can decode and parse the json like so:
<script>
var decodedJson = decodeURIComponent("{{{encodedJson}}}");
var jsonObj = JSON.parse(decodedJson);
</script>
Since anything passed to a handlebars-view will basically be injected straight into HTML, you should always pass encoded json and let the view decode it.
I tried the other suggestions in this thread. But they injected unencoded JSON into the handlebars view and that always gave me parsing errors. I have no idea how people got that to work, since it seems like Handlebars will parse variables as plain text.
I have not read up on how the Handlebars parser works - but it seems to me the only safe option is to use encoded JSON, like how I suggest in my examples.
Upvotes: 18
Reputation: 123563
The value of user.name
needs to be output as a valid JavaScript expression if you want to include it in within a <script>
, which will be reevaluating it as code.
Currently, if user.name
is "john.doe"
for example, the resulting script will be:
var foo = john.doe; // `john` is treated as an object with a `doe` property
The user.name
at least needs to be in quotes so it's understood as a string value/literal.
var foo = "{{user.name}}";
// result
var foo = "john.doe";
You can also take advantage of JSON and JavaScript's similarities in syntax, outputting JSON that JavaScript can understand as an Expression, and will already include the quotes.
Handlebars.registerHelper('json', function (content) {
return JSON.stringify(content);
});
var foo = {{{json user.name}}};
// result
var foo = "john.doe";
Note the triple {{{...}}}
in the last example to disable HTML encoding, so you don't end up with:
var foo = "john.doe"
Upvotes: 25