nodejs hapiJs: Sending, receiving data from client - javascript

I have the following files; client.js and server.js. I want to send data to my server, using ajax. I manage to send the searched username, but the domain is received on the server as undefined. I am not sure if I am missing something on the client side, or the server side, or both?
On the server side, my function should be a generic function to allow it to receive any domain and the issue the request on that domain.
Can anyone help out please?
Cliente:
$(document).ready(function(){
console.log("Ready!");
var domains=[ ]; //pass domain names into array for easier iteration
domains.push($(".facebook").find("a").text());
domains.push($(".github").find("a").text());
domains.push($(".twitter").find("a").text());
domains.push($(".instagram").find("a").text());
domains.push($(".pinterest").find("a").text());
console.log(domains);
$("#searchbutton").on('click', function(event){
var username = $("#searchname").val().trim(); // store value from searchbox
console.log(username);
if(username === ""){
event.preventDefault();
}
if(username){
var newhtml = "<p>";
newhtml += username;
newhtml += "</p>";
$(".username").html(newhtml);
$(".username").remove("newhtml");
var domainCheck = function(domainName){
$.ajax({
url: "/"+username,
type: "get",
data: {domainName: domainName, username: username},
success: function(response){
console.log(domainName);
console.log(response);
}
});
};
//send ajax request to server for each domain name to check for username availability
var len = domains.length;
for(var i = 0; i<len; i++){
domainCheck(domains[i]);
console.log(domains[i]+'\n');
}
}
});
});
Server:
var Hapi = require('hapi');
var request = require('request');
var server = Hapi.createServer('localhost', 8080);
var routes =[
{
path: "/",
method: "GET",
handler: function (req, reply){
console.log("Home page loaded and runnning!");
reply.file('index.html');
}
},
{
path: '/{username}',
method: 'GET',
handler: function (req, reply){
// this is not working. the domain name is not being received from the client side. instead its passing undefined!
request('http://www.'+ req.domain.domainName +'.com/' + req.params.username, function(error, response, body){
console.log("Request received");
console.log(response.statusCode);
if ( response.statusCode === 404 ) {
console.log( "Username " + req.params.username + " is available on " + req.domain.domains);
reply({"available":"yes"});
}
if ( response.statusCode === 200 ) {
console.log( "Username " + req.params.username + " is already taken on " + req.domain.domains);
reply({"available":"no"});
}
});
}
},
{
method: 'GET',
path: '/static/{param*}',
handler: {
directory: {
path: 'static'
}
}
}
];
server.route(routes);
server.start(function() {
console.log("Server started", server.info.uri);
});
module.exports = server;

Change req.domain.domainName to req.query.domainName. When you access request data, you need to specify whether it is in the query, in the payload, etc.

Related

Implementing CoAP protocol on node.js

Do you know any guides or tutorials about implementing CoAP protocol connection on node.js? I have to implement simple server and client application. I've checked all the resources I've found, including of course their documentation:
https://github.com/mcollina/node-coap
but it is still unclear for me.
Thank you for any help.
EDIT:
If this is implementation of server, how should look client like?
var coap = require('coap')
, server = coap.createServer()
server.on('request', function(req, res) {
res.end('Hello ' + req.url.split('/')[1] + '\n')
})
// the default CoAP port is 5683
server.listen(function() {
var req = coap.request('coap://localhost/Matteo')
req.on('response', function(res) {
res.pipe(process.stdout)
res.on('end', function() {
process.exit(0)
})
})
req.end()
})
or like this , an example for coap client
const coap = require('coap'),
bl = require('bl');
//construct coap request
var req = coap.request({
observe: false,
host: '192.168.0.93',
pathname: '/',
port: 5683,
method: 'get',
confirmable: 'true',
retrySend: 'true',
//query:'',
options: {
// "Content-Format": 'application/json'
}
})
//put payload into request
var payload = {
username: 'aniu',
}
req.write(JSON.stringify(payload));
//waiting for coap server send con response
req.on('response', function(res) {
//print response code, headers,options,method
console.log('response code', res.code);
if (res.code !== '2.05') return process.exit(1);
//get response/payload from coap server, server sends json format
res.pipe(bl(function(err, data) {
//parse data into string
var json = JSON.parse(data);
console.log("string:", json);
// JSON.stringify(json));
}))
});
req.end();
It should be like this:
const coap = require('coap')
req = coap.request('coap://localhost')
console.log("Client Request...")
req.on('response' , function(res){
res.pipe(process.stdout)
})
req.end()
Source: https://github.com/mcollina/node-coap/blob/master/examples/client.js

node-mandrill sending mail via server

this is a newbie question on using node-mandrill properly and most probably on node itself as I am still trying to learn it. But since I have seen many examples to use the api key of mandrill directly from the client side and therefore revealing it, I was wondering how exactly it was working when served but got stuck at this point:
I have an app.js serving a public folder...
app.js
var express = require('express');
var mandrill = require('node-mandrill')(API_KEY);
var app = express();
app.use(express.static('public'));
app.listen(PORT);
function sendEmail ( _name, _email, _subject, _message) {
mandrill('/messages/send', {
message: {
to: 'EMAIL',
from: [{email: _email , name: _name}],
subject: _subject,
text: _message
}
}, function(error, response){
if (error) console.log( error );
else console.log(response);
});
}
...where a client script is used to collect info from a contact form and send an email upon clicking a submit button.
form.js
var contactForm = document.getElementById( 'contactForm' );
new stepsForm( contactForm, {
onSubmit : function( form ) {
// send email
var _subject = 'Contact Request';
var _email = contactForm.elements['q4'].value;
var _name = contactForm.elements['q5'].value;
var _message = contactForm.elements['q6'].value;
sendEmail(_name,_email,_subject,_message);
}
} );
Could you please tell me what's missing/wrong?
Thanks.
You can't call your back-end function from client. You can use Jquery to make Ajax call like:
$(document).ready(function(){
$('#contactForm').submit(function(event) {
event.preventDefault();
var _subject = 'Contact Request';
var _email = contactForm.elements['q4'].value;
var _name = contactForm.elements['q5'].value;
var _message = contactForm.elements['q6'].value;
$.ajax({
url: '/sendEmail',
method: 'post',
contentType: 'application/json',
data: JSON.stringify({ subject: _subject, email: _email}),
success: function(res) {
}
})
})
})
And in your back-end:
// some lines skipped
app.post('/sendEmail', function(req, res) {
//do your stuff
})

How to extract data from XML using node.js

how to extract data from XML type rest API using node.js?
This is the code i used to get data by sending rest api request:
//Load the request module
var request = require('request');
//Lets configure and request
request(
{
url: 'http://nemo.sonarqube.org/api/resources?resource=DEV:Fabrice%20Bellingard:org.codehaus.sonar:sonar&metrics=ncloc,coverage', //URL to hit
method: 'GET', //Specify the method
headers: { //We can define headers too
'Authorization': 'Basic ' + new Buffer( 'admin' + ':'+'admin').toString('base64'),
'Content-Type': 'MyContentType',
'Custom-Header': 'Custom Value'
}
},
function(error, response, body){
if(error) {
console.log(error);
} else {
var obj=JSON.parse(response.body);
console.log(obj.id);
}
}
)
var express = require('express');
var app = express();
var server = app.listen(3000,function (){
console.log('port 3000');
}
);
When I send the request using a browser, the result appears like:
<resources>
<resource>
<id>400009</id>
<key>DEV:Fabrice Bellingard:org.codehaus.sonar:sonar</key>
<name>SonarQube</name>
<lname>SonarQube</lname>
<scope>PRJ</scope>
<qualifier>DEV_PRJ</qualifier>
<date>2015-08-04T13:10:57+0000</date>
<creationDate/>
<copy>48569</copy>
<msr>
<key>ncloc</key>
<val>879.0</val>
<frmt_val>879</frmt_val>
</msr>
<msr>
<key>coverage</key>
<val>81.8</val>
<frmt_val>81.8%</frmt_val>
</msr>
</resource>
</resources>
I want to extract the id and print it on the console using node.js.
How I want to edit the above code?
The problem is response.body is in array format, so get the first item in the array and then its id value
//Load the request module
var request = require('request');
//Lets configure and request
request({
url: 'http://nemo.sonarqube.org/api/resources?resource=DEV:Fabrice%20Bellingard:org.codehaus.sonar:sonar&metrics=ncloc,coverage', //URL to hit
method: 'GET', //Specify the method
headers: { //We can define headers too
'Authorization': 'Basic ' + new Buffer('admin' + ':' + 'admin').toString('base64'),
'Content-Type': 'MyContentType',
'Custom-Header': 'Custom Value'
}
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
var arr = JSON.parse(response.body);
var obj = arr[0];
console.log(obj.id);
}
})
var express = require('express');
var app = express();
var server = app.listen(3000, function () {
console.log('port 3000');;
});

io.connect: io is not defined but socket.io is loaded

I have built a node.js server that provides a client.html page with a list of messages from a mysql db. I can't make it work using an ajax call.
The client.html page is this:
<time></time>
<div id="container">Loading ...</div>
<script src="http://oclock.dyndns.org:8000/socket.io/socket.io.js"></script>
<!--<script src="socket.io/socket.io.js"></script>-->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
// create a new websocket
var socket = io.connect('http://oclock.dyndns.org:8000');
// on message received we print all the data inside the #container div
socket.on('notification', function (data) {
var msgs = '<div>';
$.each(data.flashmsgs,function(index,flashmsg){
msgs += "<b>Messaggio inviato da " + flashmsg.created_by + "</b><br>";
msgs += flashmsg.testo;
});
msgs += '</div>';
$('#container').html(msgs);
$('time').html('Last Update:' + data.time);
});
</script>
and the code for the ajax call is the following:
(function nodeLoader(){
$.ajax({
url: "client.html",
method: "get",
data: {hk: hk },
success: function(data){
$('#messaggi').html(data);
}
});
})();
The socket.io code is loaded but I get an error on io.connect: io is not defined. Same issue if i change the url from client.html to http://oclock.dyndns.org:8000 (the url of the node.js server that is listening for requests).
Any help is appreciated!
EDIT:
server.js
var hwkey;
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
url = require('url'),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'flipper',
database: 'oclock',
port: 3306
}),
POLLING_INTERVAL = 3000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function(err) {
// connected! (unless `err` is set)
if (err) {
console.log(err);
}
});
// creating the server ( localhost:8000 )
app.listen(8000);
function handler(req, res) {
var origin = (req.headers.origin || "*");
if (req.method.toUpperCase() === "OPTIONS"){
res.writeHead(
"204",
"No Content",
{
"access-control-allow-origin": origin,
"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
"access-control-allow-headers": "content-type, accept",
"access-control-max-age": 10, // Seconds.
"content-length": 0
}
);
return( res.end() );
}
console.log("INCOMING REQUEST: "+req.method+" "+req.url);
req.parsed_url = url.parse(req.url, true);
var getp = req.parsed_url.query;
hwkey = getp.hk;
fs.readFile(__dirname + '/client.html', function(err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(
200,
{
"access-control-allow-origin": origin,
"content-length": data.length
}
);
res.end(data);
});
}
function pollingLoop(){
// Doing the database query
var query = connection.query('SELECT id, testo, created_by FROM flashmsgs WHERE hwk="'+hwkey+'" AND letto="0"'),
//var query = connection.query('SELECT max(id), testo, created_by FROM flashmsgs'),
flashmsgs = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function(err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
updateSockets(err);
})
.on('result', function(flashmsg) {
// it fills our array looping on each user row inside the db
flashmsgs.push(flashmsg);
})
.on('end', function() {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
flashmsgs: flashmsgs
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
};
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
console.log(hwkey);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8000');
Okay, I misunderstood at first. I just investigated your live app and it appears your ajax call is pulling down an entire html document.
If you're loading markup via ajax and then inserting into the existing page, you don't want a full HTML document. Just send down the body content.
Also, the socket.io script reference should ideally be on the parent page, not the page loaded via ajax.

Long polling with Node.js and ajax

I have following server code.
var http = require('http');
var mysql = require('mysql');
var querystring = require('request');
var util = require('util');
var url = require('url');
var singer_name;
var currentmodif, lastmodif;
var requests=[];
var response;
var connection = mysql.createConnection({
host : 'localhost',
user : 'someone',
password : 'xxxxxxx',
database : 'rest', //mysql database to work with (optional)
});
connection.connect(); //connect to mysql
connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
if (err) throw err;
singer_name=rows[0].singer_name;
currentmodif=rows[0].time_added;
});
http.createServer(function (req, res) {
console.log('request received');
requests.push({
response: res,
timestamp: new Date().getTime()
});
if(req.method=='GET'){
var url_parts = url.parse(req.url,true);
lastmodif = url_parts.query.timestamp;
}
//check_update(req, res);
}).listen(9000);
setInterval(function() {
var expiration = new Date().getTime() - 30000;
for (var i = requests.length - 1; i >= 0; i--) {
//console.log("Request timestamp: "+requests[i].timestamp+" Expiration : "+expiration);
response = requests[i].response;
if (requests[i].timestamp < expiration) {
console.log("The condition is met");
response.writeHead(200, {
'Content-Type' : 'text/plain',
'Access-Control-Allow-Origin' : '*'
});
// return response
response.write('_testcb(\'ok\')', 'utf8');
response.end();
//break;
}
}
connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
if (err) throw err;
currentmodif=rows[0].time_added;
//console.log("currentmodif: "+currentmodif+" lastmodif: "+lastmodif);
if (currentmodif > lastmodif){
singer_name=rows[0].singer_name;
var _arrays = {'singer_name': singer_name, 'time': currentmodif}
var data = "_testcb"+"("+JSON.stringify(_arrays)+")";
response.writeHead(200, {
'Content-Type' : 'text/plain',
'Access-Control-Allow-Origin' : '*'
});
if (response.end(data))
console.log("Response successfully sent");
//return false;
}
});
}, 2000);
and Client code:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<title>Node.js Ajax test</title>
</head>
<body>
</body>
<script>
var timestamp = "1380020402";
function callNode() {
var time = "1380020402";
$.ajax({
url: 'http://xx.xxx.xx.xxx:9000/',
dataType: "jsonp",
data: {"timestamp":timestamp},
type: 'POST',
jsonpCallback: "_testcb",
cache: false,
timeout: 35000,
success: function(response, code, xhr) {
if ('ok' == response) {
callNode();
return false;
}
console.log(response);
timestamp = response.time;
// make new call
callNode();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + " " + errorThrown);
}
});
}
$(function () {
callNode();
});
</script>
</html>
I am trying to do a long polling. So until a data in database is updated, the response to ajax request should be paused but the above code is not working. I am making the ajax request from different domain and therefore using jsonp.
Exact problem is that currently when the data is changed in database the response doesn't get sent. It works every now and then but it is not consistently reliable.
Another problem is that the code block for time out is not working. If the request is 30 seconds old then a blank response should be sent in order to avoid the timeout from ajax.
If someone can help then I would appreciate.
Cheers.
I have figured this out. Amended code that work is as below:
Client side:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<title>Node.js Ajax test</title>
</head>
<body>
</body>
<script>
var timestamp;
function callNode() {
$.ajax({
url: 'http://xx.xxx.xx.xxx:9000/',
dataType: "jsonp",
data: {"timestamp":timestamp},
//type: 'POST', //don't need this with jsonp
jsonpCallback: "_testcb",
cache: false,
timeout: 35000,
success: function(response, code, xhr) {
if ('ok' == response) {
console.log(response);
callNode();
return false;
}
console.log(response);
timestamp = response.time;
// make new call
callNode();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + " " + errorThrown);
}
});
}
$(function () {
setTimeout(callNode, 1); //call function with setTimeout in order to avoid ugly constant browser loading
});
</script>
</html>
Server Side (server.js):
var http = require('http');
var mysql = require('mysql');
var util = require('util');
var url = require('url');
var singer_name, currentmodif, lastmodif, request, response, time_of_request;
//var requests=[];
var connection = mysql.createConnection({
host : 'localhost',
user : 'someone',
password : 'xxxxxx',
database : 'rest', //mysql database to work with (optional)
});
connection.connect(); //connect to mysql
connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
if (err) throw err;
singer_name=rows[0].singer_name;
currentmodif=rows[0].time_added;
});
http.createServer(function (req, res) {
request = req;
response = res;
time_of_request = new Date().getTime();
console.log('request received');
if(req.method=='GET'){
var url_parts = url.parse(req.url,true);
lastmodif = url_parts.query.timestamp;
}
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
//checkupdate();
}).listen(9000);
var response;
function checkupdate() {
var expiration = new Date().getTime() - 30000;
//for (var i = requests.length - 1; i >= 0; i--) {
//console.log("Request timestamp: "+time_of_request+" Expiration : "+expiration);
if (time_of_request < expiration) {
console.log("The condition is met");
// return response
response.write('_testcb(\'ok\')', 'utf8');
response.end();
}
//}
connection.query('SELECT * FROM musics WHERE id=1', function(err, rows, fields) {
if (err) throw err;
currentmodif=rows[0].time_added;
if (lastmodif == undefined)
lastmodif = 0;
console.log("currentmodif: "+currentmodif+" lastmodif: "+lastmodif);
if (currentmodif > lastmodif){
singer_name=rows[0].singer_name;
var _arrays = {'singer_name': singer_name, 'time': currentmodif}
var data = "_testcb"+"("+JSON.stringify(_arrays)+")";
//response.writeHead(200, { 'content-type':'application/json',
//'Access-Control-Allow-Origin' : '*'});
//response.write(data);
response.end(data);
console.log("Response successfully sent");
//return false;
}
});
};
setInterval(checkupdate, 2000);
The problem was with the server side. The response object was not available (it was undefined) when server wanted to reply and therefore the response was not being sent. I may have overlooked the error in the node.js's console.
This is almost a complete example of long polling with node.js with MYSQL database. This script will wait for fresh data to become available before replying to the ajax request. If fresh data (in MYSQL) is not available within 30 seconds of the request then a fake reply is made so that the request does not time out. There is a condition in ajax's success callback that re-initiates this ajax request when this demo response is received, therefore making this an infinite loop.
I have successfully tested code above and it seems to work fine. I ran the script and then updated the data in my database (mainly the time_added field) and this triggered a reply to my waiting ajax call with new data from node.js's server.
I hope this code helps someone out there.
Checkout tutorial here for further explanation: http://www.sahilsaid.com/blog/long-polling-node-js-mysql-database-ajax/

Categories