How to pass parameters between node.js and HTML? - javascript

I am a new user of node.js and mongodb and still learning. Please excuse if the question seems very simple. My node.js MongoDB query script (hello.js) is-
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/flood';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
var collec_name="99"
var field_name ="data1"
var value=311
db.collection(collec_name).find({data0:value}, {[field_name]:1, _id:0}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
The query runs fine with command- node hello.js and got the expected value result (for instance, output value of result is 0.000115). Note that var collec_name="99", var field_name ="data1" and var value=311 contain fixed values.
My HTML file (index.html) is-
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var c_n = "99";
var f = "data1";
var v = 311;
document.getElementById("demo").innerHTML = 0.000115;
</script>
</body>
</html>
Now, I want to pass the values of variable c_n, v and f from index.html to hello.js by replacing three statements of hello.js as-
var collec_name=c_n
var field_name = f
var value = v
Then, I want to pass value of result from hello.js to the index.html by replacing one statement of index.html as-
document.getElementById("demo").innerHTML = result;
So, how can I achieve these parameter passing so that if I run the index.html page, I can display the value of result on the web? Any solution script based on my scripts will be highly appreciated.

To send data between your back-end and your client you have to use AJAX, socket.io or WebSockets.
If you only have to update the back-end if the clients wants to you should use AJAX. If your client has to be notified by the back-end (Server), you should use socket.io or WebSockets for that.
Because you are using NodeJs, i would recommend you to use socket.io.
Just have a look at it:
https://socket.io/
Here a example for your code:
First install the package:
npm install -S socket.io
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
// add socket io
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
// connect to port
app.listen(3030);
var url = 'mongodb://localhost:27017/flood';
// setup server
io.on('connection', function (socket) {
// add event
socket.on('data', function (data) {
// execute after event was emitted
MongoClient.connect(url, function (err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
var collec_name = data.collec;
var field_name = data.field;
var value = data.value
db.collection(collec_name).find({ data0: value }, { [field_name]: 1, _id: 0 }).toArray(function (err, result) {
if (err) throw err;
// TODO add emmit
console.log(result);
db.close();
});
});
});
});
HTML:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script src="path/to/socket.io"></script>
<script>
var socket = io('http://localhost');
// send message
socket.emit('data', {
collec: "99",
field: "datal",
value: 311
});
// TODO add listener
document.getElementById("demo").innerHTML = 0.000115;
</script>
</body>
</html>

Finally, I was able to solve the problem. As I didn't find any perfect solution on net, I thought it will be helpful for other users (who are facing similar problem) if I post a general solution to a similar problem here. Please excuse if this is not the right place to post the solution.
My Solution: This is not the exact solution of my above example but I think it is better to provide a general solution to a similar problem so that anyone can always modify/update this solution according to his/her example/need as basic approach will be always same. At first, you need to have http, express and body-parser and you can do by following the commands:
npm install http
npm install express
npm install body-parser --save
A general problem: Suppose, I have two numbers (for instance a = 20 and b = 24 in the client HTML page and I want to sum up the numbers from the server side and get the summation result (sum = 44) back in the client side to display in the HTML page. Then use the following nodejs and ejs scripts-
index.ejs:
<html>
<head>
<title>Example solution</title>
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script type="text/javascript">
$(function(){
$('#loadRequest').click(function(e) {
e.preventDefault();
console.log('Load_button clicked');
var data = {};
data.a = 20; //input
data.b = 24; //input
$.ajax({
type: 'POST',
data: JSON.stringify(data), //input data to be sent to the server
contentType: 'application/json',
url: 'http://localhost:80/endpoint',
success: function(res) {
console.log('success');
console.log(res);
$("#demo").html(res); //summation displayed in the HTML page
}
});
});
});
</script>
</head>
<body>
<p id ="demo"></p>
<button id="loadRequest">Load</button>
</body>
</html>
server.js:
var http = require('http');
var express = require('express');
var app = express();
app.set('view engine', 'ejs'); //tell Express we're using EJS
app.set('views', __dirname + '/views'); //set path to *.ejs files
app.use('/public', express.static(__dirname + '/public'));
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
app.get('/', function(req, res) {
//render index.ejs file
res.render('index');
});
app.post('/endpoint', function(req, res){
var x = req.body.a; //received input 1 from client side
var y = req.body.b; //received input 2 from client side
console.log(x);
console.log(y);
var sum =x+y;
console.log(sum);
res.send(String(sum)); //sending summation to the client
});
http.createServer(app).listen(80);
It worked perfectly. Please let me know if you have any comment/feedback.

You can either implement an API yourself using AJAX, WebSockets or socket.io - or you can go ahead and take a look into Express framework.
Setting up a Node.js server using Express will not only provide you access to a rich API interface, it would also make your task much easier.
Using it, you can set up a simple route like this:
app.post('/compute', function(req, res){
// compute 'result'
res.send(result);
});

Related

NodeJS Middelware/Routing Data transfer

Hello i'm trying to transfer more data to the client. I have used sample code for the middleware in NodeJS express.
I want to read 2 different files and transfer the data to the client. I have managed to transfer 1 file data. How can I add multiple?
how should I do this?, I have tried 'send' and 'json' but then I cant see my front end of the website
var express = require('express');
var router = express.Router();
const fs = require('fs');
/* GET home page. */
// const myHtml = require('fs').readFileSync(<path to html>);
const myHtml = fs.readFileSync('./views/index.html', 'utf-8');
//Data from server to client, this works.
const myJson = fs.readFileSync("./apidata.json", 'utf-8');
//I want to add a second one here
const apisparkline = fs.readFileSync("./apisparkline.json", 'utf-8');
console.log("server is running");
router.get('/', function(req, res, next) {
//This works perfect
res.end(myHtml.replace(/jsonapidata/g, JSON.stringify(myJson, '', 2)));
//how should I do this?, I have tried 'send' and 'json' but then I cant see my front end of the website
res.end(myHtml.replace(/sparklinedata/g, JSON.stringify(apisparkline, '', 2)));
});
module.exports = router;
Simply use,
res.end(myHtml.replace(/jsonapidata/g, JSON.stringify({myJson,apisparkline}, null, 2)));
Better way,
res.json({myJson,apisparkline})
and then, format at client.

How take the JSON in Node.JS

I have this in Node.JS file.
var express = require('express');
var app = express();
var http = require('http').Server(app);
var cfenv = require("cfenv");
var appEnv = cfenv.getAppEnv();
http.listen(appEnv.port, appEnv.bind);
var PersonalityInsightsV2 = require('watson-developer-cloud/personality-insights/v2');
var personality_insights = new PersonalityInsightsV2({
username: '<YOUR-USERNAME>',
password: '<YOUR-PASSWORD>'
});
personality_insights.profile({
text: "<YOUR-100-UNIQUE-WORDS>",
language: 'en' },
function (err, response) {
if (err)
console.log('error:', err);
else
console.log(JSON.stringify(response, null, 2));
});
I am sending an API call but as you can see, it shows me the result in JSON in the console.
How can I make this result in JSON that shows me in the console, show it to me in an HTML?
Thank you very much!
I supose that the problem is in console.log(JSON.stringify(res,null, 2));, but, I don't know how put this in HTML.
You can't just turn JSON into HTML. JSON is a data format. HTML is a markup language. You'll manually have to create some HTML with the way you want it, and then drop in values from the JSON.
For example, you could do something like this:
else {
const html =
`<!DOCTYPE html>
<body>
<p>${response.name}</p>
`;
console.log(html);
}
That would give you some HTML like:
<!DOCTYPE html>
<body>
<p>Bob</p>
assuming response has a value of name.
It sounds like you're wanting to view the JSON on an HTML page in a browser. Something like this should help. It will start your Express server listening on whatever port you specified using appEnv.port, and will serve up myJson (which will then be assigned in your code)
var express = require('express');
var app = express();
var http = require('http').Server(app);
var cfenv = require("cfenv");
var appEnv = cfenv.getAppEnv();
var myJson;
// respond with JSON when a GET request is made to the index
app.get('/', function (req, res) {
res.send(myJson)
})
app.listen(appEnv.port);
var PersonalityInsightsV2 = require('watson-developer-cloud/personality-insights/v2');
var personality_insights = new PersonalityInsightsV2({
username: '<YOUR-USERNAME>',
password: '<YOUR-PASSWORD>'
});
personality_insights.profile({
text: "<YOUR-100-UNIQUE-WORDS>",
language: 'en' },
function (err, response) {
if (err)
console.log('error:', err);
else
myJson = JSON.stringify(response, null, 2);
});
To try this, you would open your browser to "http://localhost:appEnv.port/" (where appEnv.port is the port you chose). You should see your JSON output

Cannot read property 'insert' of undefined when trying to put data in MongoDB

I'm getting this error: "Cannot read property 'insert' of undefined" when trying to insert data into a database. The error shows on:
db.coordinates.insert({ "x" : "data.x", "y" : "data.y"})
Database name - "node5"
Collection name - "coordinates"
// Including libraries
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var static = require('node-static'); // for serving files
//db connection
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/node5');
var url = 'mongodb://localhost:27017/node5';
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server.");
db.close();
});
// This will make all the files in the current folder
// accessible from the web
var fileServer = new static.Server('./');
// This is the port for our web server.
// you will need to go to http://localhost:8080 to see it
app.listen(8080);
// If the URL of the socket server is opened in a browser
function handler(request, response) {
request.addListener('end', function () {
fileServer.serve(request, response);
}).resume();
}
// Delete this row if you want to see debug messages
io.set('log level', 1);
// Listen for incoming connections from clients
io.sockets.on('connection', function (socket) {
// Listen for mouse move events
socket.on('post', function (data) {
console.log('posted');
console.log(data);
socket.broadcast.emit('posted', data); // Broadcasts event to everyone except originating client
db.coordinates.insert({ "x" : "data.x", "y" : "data.y"})
});
});
When writing an answer, please note that I'm new to node.js and I might not understand if you tell the answer in a complex way:)
If you are using monk for your project, then you can drop the mongodb module, since it's functionality is being wrapped up by monk. From Monk's documentation, you should be doing something like:
const monk = require('monk');
const db = monk('localhost:27017/node5')
const coordinates = db.get('coordinates');
Now that you have a reference to your coordinates collection, you can use it later in your code:
coordinates.insert({ x: data.x, y: data.y });
I hope this is easy enough to understand. If it is still confusing, then please comment below and I'll elaborate further :)

Node.js: Using Socket.io in an express.js route to send message to a specific client

I have made a very casual commenting system, and now I want to add replies. So, when someone posts a reply on someone else's comment, that user must be notified that someone replied to their comment. In order to do that, when the replier clicks the reply button an AJAX post request is made to the server, the server then needs to get the id of the first commenter and send them a response text using socket.io (socket.io is not required to be used if there is another way to send the reply text with another module or express itself). This is my code so far:
app.post('/reply', function(req, res){
var commenterId = req.body.userId; // this is the id of the original commenter, not the replier
User.findOne({'_id':commenterId}, function(err, user){
user.send({'replied': req.user._id}); // this is what I need to do, and
//I don't know if this specific code works and that's why I'm asking if there is a way to do it with socket.io,
// io.to(socketId).emit('reply', 'some reply text here...'); // but if I do this I don't know how to get the socketId!
//Is there even a way to do this? Maybe with another module,
//or some express function I don't know about? And if it is done with express how would
//the client side code, look like? Thank you!
});
res.end();
});
//app.js file
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var routes = require('./routes/routes')(io);
app.use('/', routes);
//router file
var express = require('express');
var router = express.Router();
var _socket = null;
//list of socket users.once they logout delete the socket by
//delete users[_socket.userid];
var users = {};
var returnRouter = function(io) {
io.sockets.on('connection', function (socket) {
//now _Socket is available inside routes
_socket = socket;
});
router.post('/login', function(req, res) {
//authentication logic
User.findOne({'email': req.body.email}, function (err, user) {
//userid must be unique
_socket.userId= user.userId
//set session variable to store id of the user
req.session.userId = user.userId;
//now every user has a socket associated with their id
users[_socket.userId] = _socket;
});
});
router.post('/reply', function (req, res) {
var commenterId = req.body.userId;
User.findOne({'_id': commenterId}, function (err, user) {
// you can get the id of the logged in user that is the creator
//of the original post from req.session.userId
//if you have implemented session store
//the commenter user object is obtained from findOne method
users[req.session.userId].emit('notification', {
notification: user.username+' commented on your post'
}});
});
res.end();
});
return router;
};
module.exports = returnRouter;

AJAX call with Express

I am trying to append HTML dynamically with Express framework in a static HTML file that my server serves. I've found about the cheerio module that does exactly what I want, but I was wondering if there is a much cheaper way for the system instead of loading the whole HTML and appending a string.
I searched about AJAX and how to communicate with the client but I didn't manage to make it work. The code I am using with cheerio is:
exports.modify = function(req, res){
var html = fs.readFileSync(__dirname + '/../public/index.html', 'utf8');
var $ = cheerio.load(html);
var scriptNode = '<p>Source code modified</p>';
$('body').append(scriptNode);
fs.writeFile(__dirname + '/../public/index.html', $.html(), function (err) {
if (err) throw err;
console.log('It\'s modified!');
});
res.send($.html());
};
How can I do it in more 'proper' way (maybe with AJAX call)? Any suggestions would be more than welcome.
Assuming you want to handle JSON as a data type then you can setup another specific route or you can filter the request type within the current route handler :
exports.index = function(req, res) {
var data = someData.fetch();
switch(req.format) {
case 'json':
res.json(data);
break;
default:
res.render('template', {
data:data
});
}
};

Categories

Resources