I want to set a javascript variable on my index.html page when the page is returned by express.js. I am trying to use the express-expose middleware but I am not sure how to get variable set in the static html page that is rendered.
On the server I have:
app.get('/', function(req, res) {
var user = { name: 'tj' };
res.expose(user, 'user');
res.render(config.rootPath + '/public/index.html');
});
Index html I have
<script>
var myUser = user;
</script>
What I need is myUser to contain the json object user.
Examples I have seen use jade which i am not using.
You need to expose them like this
app.expose('var some = "variable";');
https://github.com/visionmedia/express-expose#raw-javascript
The way you're doing it, they're only available to the templating engine (jade). In which case you'll have to do something like this
script var some = #{variable}
Related
Here, I have use.js and use.jade.
In use.js, I am simply mapping hardcoded image variable img_01 from jade to use.js by specifying var $image= $(pclass + 'img_01');
In .js, I am assigning $image by some useful image using
$image.attr('src', useful_image)
Using img.use--img_01 in .jade, I am able to display the image (useful_image).
Now, my constraint is I don't want to hard code in .jade and let .jade display images as many as provided by .js.
So, I am able to create the array in .js of var $image=[] and then $image.push($(pclass + 'img_' + N.toString()) where N varies from 0 to K (lets say K =3).
Now I want to call these img_0, img_1, img_2 .....img_K in .jade and display them on page.
So my specific question is I am not able to iterate [img_0, img_1, img_2 .....img_K] in .jade. Can anyone tell what could be best method to do so????
Pls note: I used rendering method. For the same I used
var express = require('express');
var app = express();
But, node.js gets crashed with this itself leave aside using app.get...
You can pass object from server to client in this way.
app.get(..., function (req, res) {
var stats = { ... };
res.render('chart', { images: $arrImage });
});
For looping at client ,you can use jade#each.
each oneImage in images
img( src=oneImage.image)
Note : Jade is depricated,So try to use Pug#each
I am new to node.js and I am using Yeoman to fetch a product details from the list of products. I am getting data from a triple store database and converting to json. The only unique ID is in the form of URL with an hash encoded at last.
In demo.controller.js:
exports.index = function(req, res) {
res.json(response);
}
In index.js:
var controller = require('./demo.controller');
var router = express.Router();
router.get('/', controller.index);
module.exports = router;
Here, response output is the following json structure for URL/api/product_list:
[{
"url":"http://example.com/demo/32b9jkd902n2"
"product":"stack",
"name":"test",
"price":"233"
}, {
"url":"http://example.com/demo/5nf9djdkdks0"
"product":"flow",
"name":"dev",
"price":"433"
}]
Now, I want to get details of each product. something like URL/api/product_list/:product_url ?
Basically, when I access url with product_url from the list of products, I should be able to get the product details.
Can someone help me in implementing the URL with /api/product_list/:product_url with an output of single product?
So, as there is no other unique identifier besides the URL you could to one of the following:
Parse unique ID from the url to /api/product_list as id to the output and use that - /api/product_list/:id
Generate a hash (md5, sha1) of the whole url to the output as id and use that as an unique id.
Note: never used Yeoman before, so I don't know if you have some limitations from there.
I think /api/product_list/:url will not fly, and if it does, it sure will look ugly.
I'm trying to pass an object from my endpoint to Jade but It keeps giving me Uncaught SyntaxError: Unexpected identifier on Stat! Can someone help me please. Here is my code:
app.get('/stats', function (req, res, next) {
var stats ={
'm0t20': {a:0,b:0,c:0,d:0},
'm20t30': {a:0,b:0,c:0,d:0},
};
res.render('chart',{'stat':stats});
}
and in my jade and I cant get the value of stat:
script(type='text/javascript').
var stats= #{stat};
If you want to interpolate object from you express, the easiest and cleanest way is to serialize them.
For the moment, once interpolated, you are trying to write something like this:
var stats = [Object object];
Which isn't a valid JavaScript syntax :/
So, on the server side, serialize your object:
app.get(..., function (req, res) {
var stats = { ... };
res.render('chart', { stats: JSON.stringify(stats) });
});
And, on the client side, just use the serialized object; You'll need to use ! instead of # to prevent jade from escaping characters like quotes.
script.
var stats = !{stats};
alert(stats.myProp);
Keep in mind that you are injecting direct JavaScript code into your page.
DO NOT do that if the serialized object could contain any user input
Questions
How to serve javascript file dynamically? Specifically, the scripts maintain most of its body but with some variables changable (imagine HTML Jade template, but this is for pure javascript).
Scenario
When user or browser (http GET in general) visits /file.js passing parameter api, e.g. /file.js?api=123456, I would like to output pure javascript where I can take that 123456 and put in inside of my code, dynamically. Content-Type is application/javascript.
Sample:
var api = #{req.query.api}; //Pseudo
//The rest of my javascripts template
...
From my main .js file, I have set up the route:
app.get( '/file.js', function( req, res ) {
//Pseudo code that I would like to achieve
var name = req.query.name;
res.render( 'out_put_javascript_file_from_jade_file.jade', { name: name } );
});
So when a person visits /file.js, the script file will be rendered differently based on the parameter api passed in the URL. The only possible dynamic way I can think of is using Jade, but it doesn't allow pure javascript template. I believe there must be other solutions.
Please excuse my explanation. The problem is somewhat like this: How to generate a pure JavaScript file with Jade
If you want to do something quick and dirty, then you can do something like this (based on your example in the comments).
App init - read the .js template file and cache it:
// this should be async, but hey, not teaching you that part here yet
var fileJs = fs.readFileSync('file.js.template');
File.js:
(function() {
$(window).on('load', function() {
alert('Your api key is API_KEY_CONST');
});
})();
Request:
GET /api/file.js?key=123
Router:
app.get('/api/file.js', function(req, res) {
var key = req.query.key;
var key = fetchKeyFromDBSync(); // just to make it easier here, no async.
var out = fileJs.replace(API_KEY_CONST, key);
res.setHeader('content-type', 'text/javascript');
res.write(out);
res.end();
});
Now, this is really dumb and you should not try it at home, but it simply demonstrates how to do what you wanted.
Edit:
Depending on the file length, you might perform a bit better if you put the chunks of the file into an array, like:
var fileChunks = ['(function(){ blablabla;', 'var myAPIKey=', 'KEY_PLACEHOLDER', '; alert (myAPIKey);', '})()']
So later when you're resolving it with the real API key, you join the file.
fileChunks[2] = '12345';
var responseData = fileChunks.join('');
res.write(responseData);
But your last-accessed api key is then held in an array. Not quite future proof, but it shouls work if you need something quick.
I'm working on a web application using node.js that has a form containing basic information about a person. I need to have all records that have been added since the web application was started display on the submit page.
I believe that I need to create an array to store this information but this is where my confusion starts. I'm not sure where to create the array to add information to. I suspect it should be in app.js where I call app.post('/add', routes.add);
I think it should maybe something like this going from an example I found here How do I add a new complex entry to a javascript array?:
// Routes
app.get('/', routes.index);
app.post('/add', routes.add);
var people = [{name, country, date, email, phone}];
people.push({name, country, date, email phone});
However the array looks like it will only hold enough information for 1 person.
Please let me know if my question is not clear enough and I will try to clarify
Thanks in advance!
Edit: I believe that when I am calling routes.add this code is executed from my index.js file
exports.add = function(req, res){
res.render('add', { title: 'Person added',
name: req.body.name,
country: req.body.country,
date: req.body.birthday,
email: req.body.email,
phone: req.body.phone});
};
and in my add.jade file:
h1 Info Added
p Name: #{name}
p Country: #{country}
p Date: #{date}
p Email: #{email}
p Phone: #{phone}
There are a few things to maybe get you started.
Database
I suggest you move the database to another file, that way you may replace it with a 'real' database later. Ie. do something like this:
create a lib directory in app root,
create a db.js in that directory,
put this code in the db.js:
var database = [],
counter = 0;
// add method adds a new object to db.
exports.add = function(person) {
person.id = counter;
counter = counter + 1;
database.push(person);
return id; // we return id, so that we can use it as a reference to this object.
}
// get method retreives the object by id.
exports.get = function(id) {
return database[id]; // this will return undefined if there is no such id
};
exports.list = function(){
return database;
}
Now you have a database.
Controllers
You use the db in other files like this:
var people = require('lib/db');
// or if you're in a routes directory,require('../lib/db') or appropriate path
people.add({name: 'Sarah'}); // returns 0
people.add({name: 'Zlatko'}); // returns 1
people.get(1); // returns {name: 'Zlatko'}
Now in your routes/index.js you can include your database and have this to save or retreive an user or all users. Somehing similar to your exports.add:
var id = people.add({name: req.body.name, email: req.body.email});
res.render('add', people.get(id));
You can also create a 'people' view and just pass it {people: people.list()} object as parameters array.
I didn't include any validation, checking, anything ,to make the example more clear. This db can hold more then one person, and it's enough to get you started. And I think it is clear in what it does.
I hope this helps.