How to send a variable from express to pug? - javascript

I want to send a variable from Express to Pug.
Therefore I found already that I have to use res.render(), but if I try this, I only get an undefined variable.
In my index.js:
app.post("/example", upload.single("photo"), (req, res) => {
{... some code}
var html = "some text";
res.render("results", {
html: html
});
and in my results.pug I try to show the text as a string:
p "#{html}"
At the moment I only get two "" on my page.
But I need to show the result
Thank you for your help!!!! :)

Your issue is with how you are calling the variable in your pug template. This is the easiest way to do it:
p= html
or
p
div= html
If you really wanted to use interpolation the syntax would be:
p #{html}
I'd bet that if you View Source on your current page you will have something that looks like this:
<p>#{html}</p>

Related

Getting value from a console.log to html

The function I have written works fine and the value correctly writes to my terminal onSubmit, however I'm struggling to piece together why this code isn't updating my html.
router.post('/index', function(req, res, next) {
// ...Get form values, do calculations to get toCost value.
console.log('$' + toCost);
$(document).ready(function() {
var output = document.getElementById('cost');
output.innerHTML = toCost;
});
res.location('/');
res.redirect('/');
})
I receive the following error and jquery is loading fine.
$ is not defined
Admittedly this is an over-engineered node/express app. The code snippet lives wrapped in a route file, inside a post request.
How do I get my value onto the html?
Jade layout
extends layout
block content
form(...)
div#cost
The normal way to do this would be as follows:
router.post('/index', function(req, res) { <<< 'next' removed (only needed if using middleware)
// ...Get form values, do calculations to get toCost value.
console.log('$' + toCost);
res.render('indexTemplate', {cost: toCost}); <<< pass toCost through to jade as 'cost'
});
Then in your jade file for the indexTemplate you can reference the 'cost' variable passed in like this:
indexTemplate.jade:
extends layout
block content
form(...)
div#cost #{cost} <<< adds the cost variable to page
Then the value of toCost will appear in the resulting page.
No jQuery is required on the server side.
jQuery is made for DOM manipulations and there's no DOM on a server.
Try using 'jsdom'.
jQuery is made for client side scripting, not for server-side client manipulations.
It seems that you're trying to make changes on client-side from your backend. It doesn't work that way.
You could create a variable on backend for storing calculation result. And get this value by get query from client-side
You're tring to reach DOM (that is on client side) from NodeJS on a server side. It doesn't work that way.

Boostrapping data with Static html page with Expressjs

I am currently using static pages (will move over to Jade soon) and I want to pass some information into my index.html when the first request is made.
I know this is possible with jade and I wanted to know what my options are if I use a static page?
For example, I need something like this:
app.get('/', function(req, res) {
res.render(config.rootPath + '/public/index.html', {data: 'usernamehere'});
});
and in my index.html I have a script tag:
<script>
var currentUser = data; <-- I know this will never work...
</script>
So should I make a call from my script tag to get the information or is there another way?
Did you consider express-expose?
"Expose helpers and local variables to the client-side." See the repo.

Accessing Express.js local variables in client side JavaScript

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!

Rendering Jade template via AJAX and trying to pass/access data separate from the HTML

I am rendering a Jade template on an ajax call via res.render with Express. Problem is I want to pass back some JSON vars or Javascript objects along with the HTML.
Is this possible in an elegant way or at all? I know I can pass a script tag along with the HTML but I'm not sure how I can access those values directly within the 'data' response.
Example here:
- var someNumber = 89
h1 Hello World
li #{someNumber}
Normally in a res.render() of this template on an ajax call you would get back
<h1> Hello Wolrd </h1>
<li> 89 </li>
All in HTML format.
How do I access one of the HTML nodes in the callback? Ideally with a jQuery selector, such as $('h1 li'). I need access to the number in the call back but it doesn't seem to be grabbing it. I'm thinking listener or adding a delay or maybe I need to assign it to a string and parse it out.
Not entirely sure I understand the question. However, to pass JSON direct to the browser via Jade. In your route logic you need something like:
res.render "test",
title: "Test"
debugJson: {
'Read Folder Result' : result,
'HTTP' : {
'Req URL' : req.url,
'Req Query' : req.query,
'Req User' : req.user,
'Req Headers' : req.headers,
'Req' : req,
'Res' : res
}
}
(Sorry, that is in CoffeeScript rather than JS)
And in your Jade template, you need to have something like (in a script):
var myJson = !{JSON.stringify(debugJson)};
which will pass the JSON straight into the script. If you want it direct into the DOM, something like:
#debug !{JSON.stringify(debugJson)}
Which will dump it into a div.
If you just want to process it in the Jade template however, you can simply use a loop in Jade. See this previous StackOverflow question for how to do that.

ExpressJS Pass variables to JavaScript

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/

Categories

Resources