How to access data from res.render in Express - javascript

I want to access the data that was sent from response.render in my html file.
I have this code in my server.
app.post('/game',function(req,res){
var name = "Jude";
res.render(__dirname +'/game.html',{user:name});
});
How do i access user variable in my game.html?

You'd have to use a template language like Jade, EJS and so on. If you already have the HTML in place, try EJS.

Related

Nodejs, Express How to pass variable to route and use it in external JavaScript file?

I am working on a web app using MongoDB Express NodeJS stack and in one of the routes I am getting array from database and then passing it to route.
Code:
app.get("/badges/new", function(req, res) {
Colour.find({}, function(err, foundCoulours) {
if(err){
console.log("error: "+ err);
res.redirect("back");
} else {
res.render("badges/new",{foundCoulours:foundCoulours})
}
});
});
All done easily but here is a bit that I am stuck at the moment: I want to use jQuery to add elements onto the page depending on the result that came from server. I can do it using script tag and in-line JS on the ejs file without any problems but what I would like to do is to use external JavaScript file so my ejs wouldn't look as massive just with <script src="public/foo.js"></script>.
Question: Is there a way to pass foundCoulours to "public/foo.js" file after it was passed to route? Or maybe I can pass it straight to "public/foo.js" file from the request route.
You can sequentially load the scripts. As below:
Jade
body
script(type='text/javascript').
var foundCoulours= #{foundCoulours}
script(type='text/javascript', src="foo.js")
EJS
<script>
var foundCoulours = <%= foundCoulours>
</script>
<script src="public/foo.js"></script>
Explained:
As we are loading foundCoulours variable in global scope, it is directly accessible in foo.js, as it is loaded after the variable is initialized.

How can I forward a querystring passed to nodejs to a page served via res.render?

Within my nodejs file I am rendering a page called foo.html. Inside of foo.html, I am using ajax to pull variables from a querystring and load an appropriate xml doc accordingly.
The problem is, if I run my nodejs server, we'll call it localhost, and I append the querystring to that, then the server will consume the querystring rather than the ajax call inside of foo.html.
Is there a way to forward the querystring directly to foo.html?
From inside the nodejs file, server.js:
app.get('/', function (req, res) {
var query = req.query;
if (query) {
if (query.screen == "page1") {
res.render('foo.html');
}
}
});
i can think of 2 ways of doing this
1st way -) you can change your rendering engine and pass the query string variables as local variables to the template and store those values as variables inside a <script></script> tag
2nd way -) keep the html but don't render the file load it and modify it to contain the same script tag with the variables,
in both cases once your page is loaded your JS will be able to access the variables
-------------HTML FILE----------------
<script>
var a=/*text-to-replace-for-A*/;
var b=/*text-to-replace-for-B*/;
</script>
--------------REQUEST HANDLER-----------
var fs=require('fs'); //this goes in the require section
//this goes inside your function
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
var finalHTML=data.replace(/\/\*text-to-replace-for-A\*\//g,variableA).replace(/\/\*text-to-replace-for-B\*\//g,variableB);
res.send(finalHTML)
});
something like that should notice i am using a simple readfile and send which is not the fastest solution but is the simplest one using html modification. you can also use streams to modify the files in memory on the fly. you can find the readfile function reference at: http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback

Send JSON Object while rendering a page with Jinja2

I have an app written in webapp2 using Google App Engine. The page I want to render needs to use some variables from the backend. How can I pass variables from Python to Javascript as a JSON object?
Thanks!
//define your values dictionary
template_values = {"name": name,
"other_value" : other values}
//render your template
template = jinja_environment.get_template("path to my html file")
return self.response.write(template.render(template_values))
then in your html you can use {{name}}
In your template file, you'd need to do something like:
<script>
var your_js_object = {{your_json_dump}}
</script>
This isn't ideal, as it means that your_js_object is global, but you'd have access to the object in your js files.

Sending JSON and HTML page together in node.js

I am sending my HTML file to the client in node.js as shown below
app.get('/get', function(req, res) {
res.render(index.html);
});
Here, index.html refers to a json file.
How can I send both together or refer the json file in the client?
If you don't want to request the JSON file from the client as an independent HTTP request you can do one of the following:
Full server side rendering:
Use a template technology like moustache or handlebars, and try to render that data inline with the response. For example if you your JSON file returns a name and an address the index.html could look like:
<div>
<span>Name: {{name}} </span>
<address>Address: {{address}} </span>
<div>
Then when rendering you could pass a js object with properties name and address to the template and you wouldn't need to ask for the JSON file separately. This example follows moustache guidelines just in case I wasn't explicit enough.
Inline object
A bit like the previous solution but less elegant, you can add the full JSON response as an object with within a script tag, and then use it however you see fit. Try to append a block to he HEAD of index.html like this:
<script>
var myObject = <contents of your JSON object>
</script>
The other possible solution was just described in another answer.
I hope this helps.
HTTP only sends one resource at a time. If your page is requesting a JSON file, it needs to be served as a second request.
Alternatively, you can render HTML with a <script> block that has a variable assignment with your JSON-encoded data as a value.
You can't send two types of files back in a single request, but you could either do an ajax call in the html to get the json you need:
<script type="text/javascript">
var json_data;
$.getJSON("URL_HERE", function(data) { json_data = data; });
</script>
or add the json to the html as a javascript object via a template engine (jade shown below):
script(type="text/javascript").
var json_data = #{ JSON.stringify(JSON_OBJECT_HERE) }

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!

Categories

Resources