how to retrieve data from mongodb to javascript - node.js

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).

Related

using HTTP.request in ejs render

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());
});
});
});

how to display a realtime variable in nodejs in HTML

I am using the setInterval() function to update a few variables(prices from various API's) every 'x' seconds in NodeJS
I want to display these variables in HTML and have them update real time every 'x' seconds.
How do I go about this using Socket.io or without using it
If you don't want to use socket.io, you can use AJAX calls but I think it's the more painful way...
If you use socket.io, there are great examples on their GitHub : Chat example.
In your NodeJS :
var io = require('socket.io')(8080); // The port should be different of your HTTP server.
io.on('connection', function (socket) { // Notify for a new connection and pass the socket as parameter.
console.log('new connection');
var incremental = 0;
setInterval(function () {
console.log('emit new value', incremental);
socket.emit('update-value', incremental); // Emit on the opened socket.
incremental++;
}, 1000);
});
This code should be start in your application.
And in your view :
<html>
<body>
<pre id="incremental"></pre>
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var socket = io('http://localhost:8080'); // Connect the socket on the port defined before.
socket.on('update-value', function (value) { // When a 'update-value' event is received, execute the following code.
console.log('received new value', value);
$('#incremental').html(value);
});
</script>
</body>
</html>
My code isn't complete but shows the essential to know.
Try Templating and template engines.
Template engine are stuff that enable you to pass variables to Templates. These engines render the template file, with data you provide in form of HTML page.
I will suggest you to try 'ejs', as it very closely signify HTML files. ejs template are simply HTML syntax with placefolder for you to pass Data.
But that will require you to refresh the page continously after regular time. So you can try 'AJAX' which let you refresh part of page, simultaneously sends and receives data from server

Nodejs append backend data to html

I am using the html as content and sending the mail, but one more requirement is need to get the data from backend and need to append to the html.I am getting error of syntax at the path can anyone help me
client.query(query, function(err, result1) {
var renderTemplate = function('/index2.html', result1.rows) {
fs.readFile('/index2.html', 'utf8', function(err, file){
return ejs.render('/index2.html', result1.rows); }} });
UPDATE: I realize that ejs v1 may not be as popular, so this was edited to work with v2.
This example uses ejs, be sure to install ejs for this example to work.
I didn't write any error handling, be sure to write the error handling if this is for production.
Rendering a template with inserted data:
var fs = require('fs');
var ejs = require('ejs');
var renderTemplate = function(pathToHtmlTemplate, dataToBeInserted) {
// reads your template file to be used in the callback
fs.readFile(pathToHtmlTemplate, 'utf8', function(err, file) {
// returns a rendered html with data to driver code
return ejs.render(pathToHtmlTemplate, dataToBeInserted);
}
}
Your html template should use something like <%= data.name %> :
<ul>
<li><%=data.name%></li>
<li><%=data.email%></li>
</ul>
Further information about the library: https://github.com/mde/ejs
If your HTML file is prepared to have data appended to it then you can use fs.append like this:
fs.appendFile(pathToFile, dataToAppend, function(err) {
if (err) // Handle error
transporter.sendMail({
from : xxxx#gmail.com,
to : xxxx#gmail.com,
subject : 'Invitation',
html : pathToFile
})
})
But if you have closing tags that may cause issues...
You can use some library like nunjucks(https://mozilla.github.io/nunjucks/api.html#renderstring)
var res = nunjucks.render('foo.html', { username: 'James' });
Should give you the html you want.
I didn't try but it should work.

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 can I bootstrap models from express js into backbone at page load?

I have some data in a mongodb database and want to pass it to a backbone collection when I load the home page. One way of doing this would be to set up a node route like this:
exports.index = function(req, res){
db.users.find(function(err, docs) {
var docs_string = JSON.stringify(docs);
res.send(docs_string);
};
};
But this won't work because it won't render my jade template that pulls in the backbone code, it simply shows the JSON in plain text.
Alternatively, I could render my jade template passing in the data as a variable to jade:
exports.index = function(req, res){
db.users.find(function(err, docs) {
var docs_string = JSON.stringify(docs);
res.render('index', {
title: "Data",
docs_string: docs_string
})
});
};
Then in the jade template, have a script like this to add the users to my user collection:
script
var docs = !{docs_string};
var users = new app.Users();
_.each(docs, function(doc) {
var user = new app.User(doc);
users.add(user);
})
But this seems wrong, since I don't really want to pass the data to the jade template, I want to pass it to a backbone collection. Also, with this solution I don't know how to then include an underscore template (on the backbone side of things) into the page rendered by jade on the server side.
What is the standard way of passing data from a node server to a backbone collection?
Assuming your data is an object, you should convert it to string using JSON.stringify() and then insert in a page inside script tag, so your resulting HTML looks like this (I don't use Jade):
<script>
var data = {...}; // in template instead of {...} here should be the instruction to insert your json string
</script>
Then when the page loads, your script will be executed and the data will be available as a global variable in the browser so you can initialise backbone collection using it. This all is a good idea only to bootstrap your data on the first page load (to avoid extra request) and then use API to request data for this and other pages.
Check out Steamer, a tiny node / express module made for this exact purpose.
https://github.com/rotundasoftware/steamer

Resources