using HTTP.request in ejs render - node.js

example in Express I have a route that linked to my ejs middleware.
Code 1 :
app.all("/sample", function(req,res,next){
ejs.renderFile("./sample.ejs", {req,res,next,require,module:require("module")} {}, function(e, dt){
res.send(dt.toString());
});
});
everything fine in the first code. and in sample.ejs (second code) I want to request to some text file in Internet and return to HTML (and should use HTTP module)
Code 2:
<%
var http=require("http");
var url=require("url");
var opt = url.parse("http://website.com/thisfile.txt");
/* it will return "Hello World!" btw */
var dt = ""
var hReq = http.request(opt, function(hRes){
hRes.on("data", function(chunk){
dt+=chunk.toString();
});
});
hReq.end();
%>
<h2>Here is the data is <%= dt %></h2>
and while i try to my browser. it just give me
Code 3:
<h2>Here is the data is </h2>
where I want it gave me
Code 4:
<h2>Here is the data is Hello World!</h2>
How could I get that?
I just want to use HTTP Module or Net Socket Module. and I just want to edit the Code 2. Code 1 is permanently like that.

While EJS can run full JavaScript, you generally want to leave as much as possible out of the template and put more of your logic in your main express request handler.
Since the rendering is done server side anyway, nothing will change other than making it easier to read and test.
You should consider moving the HTTP request made in your EJS template into your app.all('/sample') handler and then just inject the result into your template. In this case that would be the final string collected from the HTTP request. You'll then end up with something like this. (This is untested code).
Also, while it is not required at all, I'd suggest taking a look at something like the request, this makes HTTP requests much easier!
var request = require('request');
app.all("/sample", function(req,res,next){
// Make the HTTP request
request('http://www.website.com/file.txt', function(err, response, body) {
// Render the ejs template
ejs.renderFile("./sample.ejs", {file: body}, function(e, dt) {
// Send the compiled HTML as the response
res.send(dt.toString());
});
});
});

Related

How to receive data passed by the server on client side

I want to pass data from the server to the client (GET request), when I was using pug I did it with
// Server:
res.render('pageToRender', { variableToPass: value })
And on the client side I just referred to it with variableToPass. How can I do this with html and javascript though? I cannot find out...
It is possible via hack by inlining string value of javascript variable in a template
Here the example:
template.pug
<p>Forbes's Pug source code!</p>
<script>
var variableToPass = JSON.parse('#{variableToPass}')
console.log(variableToPass)
</script>
server.js
res.render('pageToRender', { variableToPass: JSON.stringify(value) })

Express Render Template from String

When a GET request is made on my site, I am trying to render templates that are stored on another server. Essentially my application will make a request to this server, and the response will contain the template that I would like to use. The server's response is a dust template in the form of a string.
What is the best way to render the template?
router.get('/', function(req, res) {
var options = {
host: myHost,
path: myPath,
port: myPort};
var templateReq = http.get(options, function(response) {
var templateStr = '';
response.on('data', function(chunk) {
templateStr += chunk;
});
response.on('end', function() {
var dustParams = myDustParams;
res.render(templateStr, dustParams); //THIS DOES NOT WORK
});
});
});
I understand that render looks in the 'views' folder to search for a template.
Also, I know that you can directly send HTML to the response using 'send', but by doing this I am unable to include the dust parameters.
You can use:
res.send(templateStr);
Regarding having dust populate the params in the template, you have to compile and render it before using the res.send
I wrote an npm module to do this by extending the express framework to read a template url from the view model along with a css selector of where to inject the content of the view.
You call res.render as normal but pass template url and selector rather than layout
res.render('view-name', {
template: 'https://courseof.life/johndoherty', // external url
templateSelector: '#promo-banner' // element within layout to inject view
});
It caches the template for 30 minutes before making another call to fetch the next version.

how to retrieve data from mongodb to javascript

I am currently new to nodejs and mongodb, so please forgive me for this newbie type of question.
What I want is to pass data from my mongodb file to my js file which is running my mini-game.
What I am doing right now is using jsp tags to retrieve data from my mongodb (I am following this practice from a project that I have seen, but he is doing this on his html file which is working out well for him. for my case I was just trying my luck)
var win = <%= user.win %>;
var lose = <%= user.lose %>;
var draw = <%= user.draw %>;
How do I retrieve the data I had from my mongodb to javascript?
If you have an Node.JS with Express application, there are many ways to do it. If you're using a template engine, you could render the data as part of the HTML page in a script block (or render it directly as HTML, avoiding script). Or, you might want to use an Ajax style request and send back the data to the client.
app.get('/api/users/:id', function(req, res) {
Users.findOne({ _id : req.params.id }, function(error, user) {
if (error || !user) {
res.send({ error: error });
} else {
res.send(user);
}
});
});
Once you've got that ready, you could use jQuery's ajax function for example to call the web service.
$.ajax({
url: "api/users/" + userId,
}).done(function(user) {
// here you have a complete user object that you can use
});
The code you posted makes me think that you're using a template engine though. I would expect that there is a render method with your template HTML file:
res.render('homepage', user);
Then, in the HTML:
<script>
var win = <%= win %>;
var lose = <%= lose %>;
var draw = <%= draw %>;
</script>
As the user object is the object with current context (as it was passed as the parameter in my example above), you can just directly refer to the properties of the user object directly (just win rather than user.win).

Is there a way to get the HTML of a JADE Template before sending it via response

What I usually do is:
res.render('myJadeTemplate');
but I want to add another transformation to the html before attaching it to the response.
How can I get the rendered HTML then modify it and send it over via res.send()
If you are using Express3. There is an additional (and optional) parameter to res.render() that is a callback that will give you the rendered HTML rather than sending it directly to the client.
res.render('myJadeTemplate', function (err, html) {
// html => rendered HTML from jade template
});
Ok I found a solution:
var jade = require('jade');
var fs = require('fs');
var jadetemplate = jade.compile(fs.readFileSync('code.jade', 'utf8'));
var html = jadetemplate({
params:"{Some parames}"
});
console.log(html);
Thanks for this thread
Node says Jade has no method "renderFile", why?

How to use Node.js to build pages that are a mix between static and dynamic content?

All pages on my 5 page site should be output using a Node.js server.
Most of the page content is static. At the bottom of each page, there is a bit of dynamic content.
My node.js code currently looks like:
var http = require('http');
http.createServer(function (request, response) {
console.log('request starting...');
response.writeHead(200, { 'Content-Type': 'text/html' });
var html = '<!DOCTYPE html><html><head><title>My Title</title></head><body>';
html += 'Some more static content';
html += 'Some more static content';
html += 'Some more static content';
html += 'Some dynamic content';
html += '</body></html>';
response.end(html, 'utf-8');
}).listen(38316);
I'm sure there are numerous things wrong about this example. Please enlighten me!
For example:
How can I add static content to the
page without storing it in a string as a variable value with += numerous times?
What is the best practices way to build a small site in Node.js where all pages are a mix between static and dynamic content?
Personally, I'd use a server that has higher level constructs. For instance, take a look at the expressjs framework - http://expressjs.com/
The constructs you'll be interested in from this package are:
Truly static files (assets etc): app.use(express.static(__dirname + '/public'));
A templating language such as jade, mustache, etc:
http://expressjs.com/en/guide/using-template-engines.html
https://github.com/visionmedia/jade/
You'll want to look up 'locals' and 'partials' for embedding small bits of dynamic content in mostly static content
For example in jade:
!!! 5
html(lang="en")
head
title= pageTitle
script(type='text/javascript')
if (foo) {
bar()
}
body
h1 Jade - node template engine
#container
- if (youAreUsingJade)
p You are amazing
- else
p Get on it!
Becomes:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Jade</title>
<script type="text/javascript">
if (foo) {
bar()
}
</script>
</head>
<body>
<h1>Jade - node template engine</h1>
<div id="container">
<p>You are amazing</p>
</div>
</body>
</html>
If you prefer something a little less drastic I would say look at mustache or one of the other engines that looks a bit more like regular-sauce html.
Alternative you can just use jsDOM. This means you have a DOM object you can manipulate on the server to add your dynamic content, then you can just flush the DOM as a HTML file / string
These days the answer is not so straightforward.
If you don't need to be indexed by Google, consider making a single-page application using socket.io and client-side templates such as jQuery Templates. There are even emerging node.js frameworks for this type of architecture, e.g. socketstream.
If you need to be indexed by Google, do you need your dynamic content to be indexed? If yes,
consider using express and server-side templates such as ejs, jade or mustache. Another (discouraged) approach might be to generate XML from JSON on server and use an XSLT front-end.
If you need only static content to be indexed, consider using express on server, but don't generate any dynamic HTML on server. Instead, send your dynamic content in JSON format to client using AJAX or socket.io, and render it using client-side templates such as jQuery Templates.
Don't consider server-side DOM: DOM doesn't scale for complex layouts, you will sink in a sea of selectors and DOM calls. Even client-side developers understood that and implemented client-side templates. A new promising approach is weld library. It offers best of both worlds, but it is not mature yet to be used in production (e.g. simple things like conditional rendering are not supported yet).
One good way is to use a templating engine. You can store the templates as separate files, and the templating engine has the ability to make the content dynamic. Personally I use yajet (http://www.yajet.net/) which is written for the web but works fine with node, and there are numerous template engines for node on npm.
One of the best things I found is to use NodeJS, Express and Mustache...
You can create your HTML pages as you normally would using Mustache syntax for placeholders for your variables {{name}}...
When a user hits your site, express routs the slug to the correct template...
NodeJS get's the file...
NodeJS get's the dataset from a DB...
Run it through Mustache on the server...
Send the completed page to the client...
Here is a scaled back version I wrote on my blog. It's simple but the idea is pretty sound. I use it to quickly deploy pages on my site.
http://devcrapshoot.com/javascript/nodejs-expressjs-and-mustachejs-template-engine
I went this route because I didn't want to learn all of the extra syntax to write a language I already knew (html). It makes more sense and follows more of a true MVC pattern.
First deliver only static HTML files from server to the client. Then use something like AJAX / server.io to serve the dynamic content. IMO Jade is really ugly for writing HTML code and its better to use a template engine.
I did some Google and found some code by this fellow, its good if you are doing it for PoC / learning.
var server = require('./server');
var controller = require("./controller");
var urlResponseHandlers = require("./urlResponseHandlers");
var handle = {};
handle["/"] = urlResponseHandlers.fetch;
handle["/fetch"] = urlResponseHandlers.fetch;
handle["/save"] = urlResponseHandlers.save;
server.start(controller.dispatch, handle);
Here is how the logic for handling URLs is displayed -
var staticHandler = require('./staticHandler');
function dispatch(handler, pathname, req, res) {
console.log("About to dispatch a request for " + pathname);
var content = "Hey " + pathname;
if (typeof handler[pathname] === 'function') {
content += handler[pathname](req);
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write(content);
res.end();
} else {
console.log("No request handler found for " + pathname);
staticHandler.handleStatic(pathname, res);
}
}
Here is how static files can be handled -
function handleStatic(pageUrl, response) {
var filename = path.join(process.cwd(), pageUrl);
path.exists(filename, function (exists) {
if (!exists) {
console.log("not exists: " + filename);
response.writeHead(404, {
'Content-Type': 'text/html'
});
response.write('404 Not Found\n');
response.end();
return;
}
//Do not send Content type, browser will pick it up.
response.writeHead(200);
var fileStream = fs.createReadStream(filename);
fileStream.on('end', function () {
response.end();
});
fileStream.pipe(response);
return;
});
}
exports.handleStatic = handleStatic;
I liked the idea. All code copied from this link!
.
A solution have found to this, without using any other modules and or other script is to make the calling script into a module and include it with the function require().
With this solution I can use javascript which ever way I want
What I would do is make an ajax call to a nodejs script (www.example.com/path/script.js)
script.js would need to be built like a module with the exports.functionName=function(){...}
After that include it in your webserver function require(pathToTheScript).functionName(res,req)
You will also need to end the response in the functionName(res,req) by doing res.end();

Resources