Node.js and express + hbs - unexpected identifier when passing variable to template - javascript

I have a node express app, and I am attempting to pass a variable through when rendering my index.hbs file, like so:
<!DOCTYPE html>
<html>
<body>
Hello.
Login with Facebook
{{req}} <!-- this works fine(ish) -->
<script>
var request = {{req}}; // This throws an error
console.log(request);
</script>
</body>
</html>
The {{req}} template variable gets outputted as [object Object] as expected, but when attempting to pass it through via javascript, I get Unexpected identifier thrown in console. I tried modifying to use triple curly braces instead of double curly braces but that didn't seem to make a difference.
What is the correct way to set template variables using javascript?

This is because your template engine is replacing {{req}} with only strings.
If you want to use {{req}} in your javascript tag. Using JSON.stringify(req) to pass in template engine as parameter and in your javascript tags using triple "triple-stash" {{{req}}} to parse the string into object
About triple-stash the doc can be found
http://handlebarsjs.com/ in HTML Escaping part
Hope it helps
Edited:
Find similar answer here
Passing an object to client in node/express + ejs?

I had this same problem with EJS. I was able to pass the object from my Express server to the template by stringifying the object:
//express server
res.render('index', {req: JSON.stringify(data)})
//template
var request = {req}

Related

How to set ejs data to data atribute and parse it in client side js?

I am trying to send leaderboard data from the server to the client side javaScript. Heres my server side javascript.
const leaderboard = [[dog,cat],[car,bus],[foo,bar]]
const toJson = JSON.stringify(leaderboard)
res.render('games/dodge.ejs', {
leaderboard: toJson
})
Here is how my ejs file recives it
<div data-leaderboard="<%= leaderboard%>"></div>
and then there is the clientside js dodge_leaderboards.js
const leaderboardData = document.querySelector("[data-leaderboard]")
console.log(leaderboardData)
When I run this code it returns an error that says Uncaught SyntaxError: Identifier 'leaderboardData' has already been declared (at dodge_leaderboards.js:1:1)
Also the console.log returns null.
I am trying to assing the arrays inside the big array to own variables, but now I am having problems with just a simple console.log. What do you think is causing the problem, I am also curios to hear how to parse the array.
Okay I got it working I forget to put ".dataset.leaderboard" after the leaderboardData
const leaderboardData = document.querySelector("[data-leaderboard]")
console.log(leaderboardData.dataset.leaderboard)

Unexpected Identifer when logging an array

I am sending over an array from node/express to my frontend.
like so:
res.render({product: req.product_data });
Now on the front end, I am purely testing to see if it is there and i do this:
<script>
console.log(<%= product %>);
</script>
From here In the browser's console it say's Uncaught SyntaxError: Unexpected identifier
Looks like so in the sources:
console.log([object Object]);
I've tried to JSON.stringify it,
<script>
console.log(<%= JSON.stringify(product) %>);
</script>
Output:
console.log([{"product_id":11089187470}]);
and when i do that I get this error:
Uncaught SyntaxError: Unexpected token &
How should I go about this?
The res.render function is used server side by express to render template files (like jade/pug).
The JSON object containing variables you pass into the render function (typically as the 2nd argument, since the first argument specifies the template file you want to render) is for you to use in your server side templates only, it will not be available once the file is rendered and sent over to the client.

How to add stringified script tag in express + jade/pug

I have express using pug as a view. My index.pug has the following:
script(type='text/javascript').
window.__DATA__ = !{payload}
where payload is a json object. It has been stringified in the render function of express:
res.render('index', {
payload : JSON.stringify({
"anExample": "<script></script>"
})
})
When my Json object has </script> it terminates my window.__DATA = function early due to the ending script tag. How can I prevent this from blowing up my page? Is this a limitation of Pug or Express or the browser?
You're going to have to "break up" the string containing the script tags.
Something like this should work:
"anExample": "<script></scr" + "ipt>"
This way, </scr" + "ipt> won't be interpreted as a closing script tag.
After asking around the solution is to use a stringify library instead of using the provided JSON.stringify function.
Specifically I used the npm module js-stringify which changes the < characters into unicode in addition to stringifying the json. Hence that is then able to be inserted into a a templating engine like Pug. Pug can then unescape it with !{my_stringified_json}. Since it unescapes unicode back to its original, the json ends up being 'anExample: '<script></script'> instead of it's unicode equivalent.

embed javascript ojbect in jade template from controller

I'm using jade to do all my rendering, and I"m passing my data from my controller in node into my page template.
I want to add an object inline with javascript... I have a variable app in a js file, and I want to include more data into that app object. I have the following:
script(type="text/javascript")
app.stations = !{page_data.station_info}
Which I would want to output as
script(trype="text/javascript")
app.stations = [{my json object}]
But instead it's rendering like this:
<script type="text/javascript">
<app class="stations">= [my json object]
</app>
EDIT:
After an hour of research I figured it out: (you need to put a . after script
script.
app.stations = JSON STUFF
After an hour of research I was able to figure it out... You do script. and then write your javascript normally. See below
script.
app.stations = JSON STUFF

Passing Google App Engine datastore models to javascript code

I know that the Jinja2 library allows me to pass datastore models from my python code to html and access this data from inside the html code as shown in this example . However Jinja2 isn't compatible with javascript and I want to access the data inside my Javascript code . What is the simplest templating library which allows to iterate over my datastore entities in Javascript ? I've heard about things like Mustache and Jquery , I think they look a bit too complicated. Is there anything simpler?
You should create a python controller which serves JSON formatted data, which any Javascript library (especially jQuery) can consume from. Then, setup the Jinja2 template to contain some Javascript which calls, loads and displays said data.
One more approach to consider: If the Python object is not dynamic, you may want to use json.dumps() to store it as a TextProperty, and simply JSON.parse(unescape(model_text)) on the JS side. Reduces the overhead, and memory hit which can be important when trying to stay within an F1 limit. For example, I run an instance that very easily runs inside an F1. There is one large dictionary object that we deliver. Were this object to exist as a Python dictionary inside the instance we would kill the instance due to the soft memory limit. Using the TextProperty approach we can pass this large dict to the client without any issues. (Note: we did have to momentarily boost our instance up to an F4 when initially creating this object -- something incredibly easy inside the Admin web page.) With more dynamic objects, answers above apply.
Jinja2 and Javascript play fine together. You need to arrange to have template expansion emit your Python data structures into a JS-friendly form.
https://sites.google.com/a/khanacademy.org/forge/technical/autoescape-in-jinja2-templates covers it fairly well. (Note the use of the escapejs filter.)
It works. I had to serialize(convert) my datastore entities to json format, which Javascript understands well. I created a function which converts every instance of my datastore into a dictionnary then encapsulates all these instances into a list which is then converted to Json using json.dumps. When I pass this result to the Java script , I can then easily access my values as seen below.
import json
import webapp2
from google.appengine.ext import db
import jinja2
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
# serialize datastore model to JSON format
def serialize(model):
allInstances = model.all() # fetching every instance of model
itemsList = [] #initial empty list
for p in allInstances:
d = db.to_dict(p)
itemsList.append(d)
return json.dumps(itemsList)
class myModel(db.Model):
v = db.FloatProperty()
c = db.FloatProperty()
tdate = db.DateTimeProperty(auto_now_add=True)
class MainPage(webapp2.RequestHandler):
def get(self):
myModel(v=4.5, c=3.0).put()
#creating template variables
template_values = {
'json_data': serialize(myModel)
}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_values))
Inside my 'index.html' file, I have:
{% autoescape true %}
<!DOCTYPE html>
<html>
<head>
<title> webpage </title>
<script type="text/javascript">
// I retrieve my data here
var results = "{{ json_data }}";
for(var i = 0; i < db_results.length; i++) {
document.write("myModel instance:" + i + results[i] + "<br>");
}
</script>
</head>
<body>
</body>
</html>
{% endautoescape %}
It has nothing to do with compatibility. Jinja is server side templating. You can use javascript for client side coding.
Using Jinja you can create HTML, which can be accessed by javascript like normal HTML.
To send datastore entities to your client you can use Jinja to pass a Python list or use a json webservice.

Categories