I have some server-side ejs templates I'm converting to jade for my node.js/express app, but there's one piece of ejs code that I"m a bit unsure of how to properly write in jade. Here's the snippet.
<script type="text/javascript">
window.user = <%- user || 'null' %>;
</script>
I tried doing something like this in jade, but it's obviously wrong since user is returned as undefined.
script.
window.user = user || 'null';
I also tried using a ternary operation, which does't give an error but also doesn't return a user.
script.
window.user ? user : 'null';
I basically have a user object the server controller is passing to the server template. What's the proper way to handle passing objects from the controller to the view? I'm a bit of a back end development noob so I apologize if this is a silly question.
This works, if user is falsy (null, undefined, empty string etc.):
script(type='text/javascript').
window.user = "#{user}" || null;
If you are certain not to escape the users value, which means you may be vulnerable to CSS-attacks, you may use !{user} instead of #{user}.
I have bean trying the snippet here: http://jade-lang.com/demo/
Related
This is my code in Flask
data = {"Bird" : "Its a bird!"}
#app.route('/store')
def store():
return render_template('store.html', data = data)
This is my code in Javascript
<script>
var val = "Bird";
var something = '{{ data[' + val +'] }}';
</script>
I'm not sure what i'm doing wrong but I cant seem to get something to be "Its a bird!".
Any ideas?
You have to keep in mind that Jinja2 template rendering happens before the JavaScript is executed. You can see this in the fact that you render the template and then return it to the user (or their browser).
Therefore, anything that comes out of that template render process, must be valid JavaScript in order to run. Also, Jinja2 does not know anything about HTML, JavaScript or really any other language.
Putting this knowledge into use would basically mean that you need to render the required data into valid JavaScript:
<script>
var mapping = {{ data | tojson }};
var val = "Bird";
var something = mapping[val];
</script>
Personally, however, I would avoid templating JavaScript code and figure out some other way or handling dynamic data.
I have been poking around the web but have not been able to find an example which works for me. It seems as though it is a simple mistake as I have seen multiple examples that are very similar, but when I try following these I keep getting errors (mainly SyntaxError: invalid property id).
Python code (in Django view):
my_dict = {'mykey' : 'myvar'}
jtest = json.dumps(my_dict)
context = {'form': form, 'test_dict' : jtest}
return render(request, "browsefiles.html", context)
Javascript:
<script type="text/javascript">
var data = {{ test_dict }};
</script>
Error:
SyntaxError: invalid property id
If someone could help me find what is causing this error that would be greatly appreciated. I would like to access the dictionary in the in the javascript code segment.
Django will escape special characters in your page and the browser cannot recognize the object. You must mark it as safe for Django to leave it alone:
<script type="text/javascript">
var data = {{ test_dict|safe }};
</script>
I have a custom template tag that returns suppose name of a student and roll number if passed as an argument id of the student.
#register.inclusion_tag('snippet/student_name.html')
def st_name_tag(profile, disp_roll=True, disp_name=True):
#some calculations
return {'full_name':student.name,
'roll':student.roll_number,
}
The template(included) consists of some Html file which is written in a single line(to avoid unterminated string literal error from js).
I simply want to call the st_name_tag from inside the JS function.
My JS looks like:
{% load profile_tag %}
<script type = "text/javascript">
eventclick : function(st){
var div = ('<div></div>');
var st_id = st.id;
if (st.status == 'pass'){
div.append('<p>Student Name:{% st_name_tag '+st_id+' %}</p>');
}
}
So far I tried the above method along with removing the + and '' signs from st_id varaible. That hasnt helped me at all. Help Please!
You are trying to render a template based on the interaction by user. The first happens on the server (server-side as it is often referred to), and the latter happens on the user's browser.
The order that these happen is first to render the template on server, send and present in browser, then user interacts with js. Because of this fact, as I mentioned in the comment, it is not possible to affect the template rendered within javascript.
I would recommend you to use ajax in order to accomplish this. Whenever an iteraction occurs, you asynchronously make a request to the server to present you with new data.
Curious if I'm doing this right and if not how you guys would approach this.
I have a Jade template that needs to render some data retrieved from a MongoDB database and I also need to have access to that data inside a client side JavaScript file.
I'm using Express.js and sending the data to the Jade template as follows :
var myMongoDbObject = {name : 'stephen'};
res.render('home', { locals: { data : myMongoDbObject } });
Then inside of home.jade I can do things like :
p Hello #{data.name}!
Which writes out :
Hello stephen!
Now what I want is to also have access to this data object inside a client side JS file so I can manipulate the Object on say a button click before POSTing it back to the server to update the database.
I've been able to accomplish this by saving the "data" object inside a hidden input field in the Jade template and then fetching the value of that field inside my client-side JS file.
Inside home.jade
- local_data = JSON.stringify(data) // data coming in from Express.js
input(type='hidden', value=local_data)#myLocalDataObj
Then in my client side JS file I can access local_data like so :
Inside myLocalFile.js
var localObj = JSON.parse($("#myLocalDataObj").val());
console.log(localObj.name);
However this stringify / parsing business feels messy. I know I can bind the values of my data object to DOM objects in my Jade template and then fetch those values using jQuery, but I'd like to have access to the actual Object that is coming back from Express in my client side JS.
Is my solution optimal, how would you guys accomplish this?
When rendering is done, only the rendered HTML is send to the client. Therefore no variables will be available anymore. What you could do, is instead of writing the object in the input element output the object as rendered JavaScript:
script(type='text/javascript').
var local_data =!{JSON.stringify(data)}
EDIT: Apparently Jade requires a dot after the first closing parenthesis.
I do it a little differently. In my contoller I do this:
res.render('search-directory', {
title: 'My Title',
place_urls: JSON.stringify(placeUrls),
});
And then in the javascript in my jade file I use it like this:
var placeUrls = !{place_urls};
In this example it's used for the twitter bootstrap typeahead plugin. You can then use something like this to parse it if you need to :
jQuery.parseJSON( placeUrls );
Notice also that you can leave out the locals: {} .
Using Jade templating:
If you are inserting #Amberlamps snippet of code above an included static HTML file, remember to specify !!! 5 at the top, to avoid having your styling broken,
in views/index.jade:
!!! 5
script(type='text/javascript')
var local_data =!{JSON.stringify(data)}
include ../www/index.html
This will pass in your local_data variable before the actual static HTML page loads, so that the variable is available globally from the start.
Serverside (using Jade templating engine) - server.js:
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.get('/', ensureAuthenticated, function(request, response){
response.render('index', { data: {currentUser: request.user.id} });
});
app.use(express.static(__dirname + '/www'));
You don't need to pass the locals variables in render call, locals variables are globals. On your pug file call don't put keys expression e.g #{}. Just use something like:
base(href=base.url)
where base.url is app.locals.base = { url:'/' };
Have you heard of socket.io? (http://socket.io/).
An easy way to access the object from express would be to open a socket between node.js and your javascript. This way data can be easily passed to the client side and then easily manipulated using javascript. The code wouldn't have to be much, simply a socket.emit() from node.js and a socket.on() from the client. I think that'd be an effective solution!
I am completely lost on this; I am using NodeJS to fetch a JSON and I need to pass the variable to my page and have JavaScript use the data.
app.get('/test', function(req, res) {
res.render('testPage', {
myVar: 'My Data'
});
That is my Express code (very simple for testing purposes); now using JADE I want to gather this data which I know to render on the page is simply
p= myVar
But I need to be able to gather this data in JavaScript (if possible within a .js file) but for now just to display the variable in an Alert box I have tried
alert(#{myVar})
And many others if anyone can help be much appreciated
Try the following:
alert('!{myVar}')
It's a good idea to JSON encode the data if is more than just a string.
alert('!{JSON.stringify(myVar)}')
As Timothy said:
<script type="text/javascript"> var myVar = #{JSON.stringify(myVar)}; </script>
This can also be done as follows in if you don't like to write HTML in Jade/Pug templates:
script
var myVar = !{JSON.stringify(myVar)};
var myVar2 = !{JSON.stringify(myVar2)};
Update: For Express 4 and Pug use script. instead of script so that it will be rendered as javascript instead of html.
Well, Javascript (and V8) has a built in function to render JSON from a object, and JSON happens to be syntactially compatible with Javascript.
So the easiest way to do what your trying to do would be:
<script type="text/javascript>var myVar = #{JSON.stringify(myVar)};</script>
And, yes, you can use HTML in a Jade template.
I know I'm a bit late to the party, but I actually wrote a module (JShare) a few months ago to solve this exact problem. Check it out: https://npmjs.org/package/jshare
You could leverage Now.js for this. It easily allows you to share variables client/server side real-time.
Check it out: http://www.nowjs.com/