Accessing Express.js local variables on the client side of JavaScript

Curious if I do it right, and if not the way you guys approach this.

I have a Jade template that should display some data retrieved from a MongoDB database, and I also need to have access to this data inside the client side JavaScript file.

I use Express.js and send the data to the Jade template as follows:

var myMongoDbObject = {name : 'stephen'}; res.render('home', { locals: { data : myMongoDbObject } }); 

Then inside home.jade I can do things like:

 p Hello #{data.name}! 

What writes out:

 Hello stephen! 

Now what I want also has access to this data object inside the client-side JS file so that I can manipulate the object, say, by clicking a button before sending it back to the server to update the database.

I was able to accomplish this by storing the "data" object inside the hidden input field in the Jade template, and then extracting the value of this 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 as follows:

Inside myLocalFile.js

 var localObj = JSON.parse($("#myLocalDataObj").val()); console.log(localObj.name); 

However, this difficult business / litigation feels dirty. I know that I can bind data object values ​​to DOM objects in my Jade template and then retrieve these values ​​using jQuery, but I would like to have access to the actual object returned from Express in my JS client side.

Is my solution optimal, how would you guys do it?

+62
javascript pug express
Jun 06 '12 at 18:03
source share
5 answers

When rendering, only processed HTML is sent to the client. Therefore, there will be no variables. What you could do, instead of writing the object in the input element, displays the object as visualized JavaScript:

 script(type='text/javascript'). var local_data =!{JSON.stringify(data)} 

EDIT: Apparently, Jade needs a dot after the first closing parenthesis.

+66
Jun 06 '12 at 18:17
source share

I do it differently. In my controller I do this:

 res.render('search-directory', { title: 'My Title', place_urls: JSON.stringify(placeUrls), }); 

And then in javascript in my jade file, I use it like this:

 var placeUrls = !{place_urls}; 

In this example, it was used for plugins like twart bootstrap. Then you can use something like this to parse it if you need:

 jQuery.parseJSON( placeUrls ); 

Note that you can leave the locales: {}.

+13
Jun 06 '12 at 18:26
source share

Have you heard about socket.io? (Http://socket.io/). An easy way to access an object from an expression was to open a socket between node.js and your javascript. Thus, data can be easily transferred to the client side, and then easily manipulated using javascript. The code should not be big, just socket.emit() from node.js and a socket.on() from the client. I think it will be an effective solution!

+2
Jun 06 '12 at 18:17
source share

Using the Jade Template:

If you paste the @Amberlamps code snippet above the included static HTML file, be sure to include !!! 5 above so as not to break your style, in views / index.jade :

 !!! 5 script(type='text/javascript') var local_data =!{JSON.stringify(data)} include ../www/index.html 

This will be passed in your local_data variable before the actual static HTML page is loaded so that this variable is accessible globally from the very beginning.

Serverside (using the 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')); 
+1
Nov 06 '13 at 13:00
source share

You do not need to pass locals variables in the rendering call, locals variables are global. Do not expose key expressions in a call to a fraudster, for example, #{} . Just use something like: base(href=base.url)

where base.url is app.locals.base = { url:'/' };

0
Nov 06 '16 at 9:21
source share



All Articles