respond json object with node.js - javascript

I have the following code:
var http = require('http')
,https = require('https')
,fs = require('fs'),json;
var GOOGLE_API_KEY = process.env.GOOGLE_API_KEY;
var FUSION_TABLE_ID = "1epTUiUlv5NQK5x4sgdy1K47ACDTpHH60hbng1qw";
var options = {
hostname: 'www.googleapis.com',
port: 443,
path: "/fusiontables/v1/query?sql=SELECT%20*%20"+FUSION_TABLE_ID+"FROM%20&key="+GOOGLE_API_KEY,
method: 'GET'
};
http.createServer(function (req, res) {
var file = fs.createWriteStream("chapters.json");
var req = https.request(options, function(res) {
res.on('data', function(data) {
file.write(data);
}).on('end', function() {
file.end();
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
console.log(req);
res.writeHead(200, {'Content-Type': 'application/json'});
res.end('Hello JSON');
}).listen(process.env.VMC_APP_PORT || 8337, null);
how do i return the json object rather then the 'Hello JSON'?

Don't store the received data in a file, put it in a local variable instead, and then send that variable in res.end():
var clientRes = res;
var json = '';
var req = https.request(options, function(res) {
res.on('data', function(data) {
json += data;
}).on('end', function() {
// send the JSON here
clientRes.writeHead(...);
clientRes.end(json);
});
});
Note that you have two res variables - one for the response you're sending back to your own clients, and one which is the response you're receiving from Google. I've called the former clientRes.
Alternatively, if you're just going to proxy the information unmodified, you can just put clientRes.write(data, 'utf8') inside the res.on('data') callback:
http.createServer(function (clientReq, clientRes) {
var req = https.request(options, function(res) {
res.on('data', function(data) {
clientRes.write(data, 'utf8');
}).on('end', function() {
clientRes.end();
});
clientRes.writeHead(200, {'Content-Type: 'application/json'});
clientReq.end().on('error', function(e) {
console.error(e);
});
});

Related

Ajax post response returns empy object

I have recently started using Node.js and jQuery and I can't figure out what's wrong in my project.
I have a client application that sends a post request to a node js server; this server gets the datas from the post and performs a query; finally it should send back to the client a json containing the informations retrieved from the previous query. The problem is that the response sent by node js is an empty object( {} ) and I don't know why.
Here my source code:
Node JS:
var http = require("http");
var url = require('url');
var querystring = require('querystring');
var express = require('express');
var cookieParser = require('cookie-parser');
var mysql = require('mysql');
var con = mysql.createConnection({
host: "",
user: "",
password: "",
database : ''
});
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cookieParser());
app.post('/search',function(req, res) {
if (req.method == 'POST') { //PUT Only
var body = '';
req.on('data', function (data){body += data;});
req.on('end', function () {
var post = querystring.parse(body);
console.log("Dati in ingresso > " + JSON.stringify(post));
//res.writeHead(200, {'Content-Type': 'text/plain'})
query("SELECT Nome FROM Mood WHERE Nome LIKE \'" + post.data + "%\'",res);
});
}else{
console.log("Not POST request")
res.end();
}
});
var query = function(q,res) {
var results = {};
con.query(q, function (err, result, fields) {
if (err) throw err;
results = JSON.stringify(JSON.parse(JSON.stringify(result))[0].Nome);
console.log("Risultati query: ");
console.log(results);
});
res.json(results);
res.end();
}
app.listen(8888);
Client:
$("document").ready(function () {
$('#search-box').on('input propertychange', function(e){
var input = $(this).val();
var array = ['prova1','prova2','prova3'];
var ul = $('#results-options ul');
$.ajax({
type: "POST",
url: "/search",
data: {data : input},
contentType: "application/json",
success: function(d) {
console.log(d);
console.log(JSON.stringify(d));
console.log(JSON.parse(d));
},
error: function(d) {
console.log("Error");
}
});
$('#results-options').show();
});
$("#results-options").on('click',function (e) {
$('this').show();
e.stopPropagation();
})
$(document).on('click', function(){
$('#results-options').hide();
})
});
As I stated above, your query function is sending back a response before the query to the database has finished. That's why it is coming back empty. I moved the res.json(results); res.end(); code inside the callback of the DB query.
var query = function(q,res) {
var results = {};
con.query(q, function (err, result, fields) {
if (err) throw err;
results = JSON.stringify(JSON.parse(JSON.stringify(result))[0].Nome);
console.log("Risultati query: ");
console.log(results);
// I moved the code here
res.json(results);
res.end();
});
// Your old code
// res.json(results);
// res.end();
};

Node Restify use case to get data gives a "ResourceNotFound"

I just started working with Nodejs.
I am using Restify to get data from: http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo'.
My code below gives me an error: {"code":"ResourceNotFound","message":"/ does not exist"}
var restify =require("restify");
var server = restify.createServer();
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.get('http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo', function (req, res) {
console.log(req.body);
res.send(200,req.body);
});
server.listen(7000, function () {
console.log('listening at 7000');
});
That's because Restify is for creating REST endpoints, not consuming them. You should check out this SO post for help consuming data from an API.
e.g. create test.js with the following:
var http = require('http');
var options = {
host: 'api.geonames.org',
path: '/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo'
};
var req = http.get(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
// Buffer the body entirely for processing as a whole.
var bodyChunks = [];
res.on('data', function(chunk) {
// You can process streamed parts here...
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
console.log('BODY: ' + body);
// ...and/or process the entire body here.
})
});
req.on('error', function(e) {
console.log('ERROR: ' + e.message);
});
then run node test.js.
I found what I was looking for. You can use restify client to get JSON data:
Here is my solution:
var restify = require("restify");
function getJSONDataFromUrl(){
var query = "?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo";
var options = {};
options.url = "http://api.geonames.org";
options.type = options.type || "json";
options.path = "/citiesJSON" + query;
options.headers = {Accept: "application/json"};
var client = restify.createClient(options);
client.get(options, function(err, req, res, data) {
if (err) {
console.log(err);
return;
}
client.close();
console.log(JSON.stringify(data));
return JSON.stringify(data);
});
}
getJSONDataFromUrl();

http request get body

I am a beginner with node so excuse me if this question is too obvious. Also I tried the official documentation but I could resolve this problem.
My node server is communicating with an external api through a service.
This is what I ve got so far in my service api-service.js :
var http = require('http');
exports.searchNear = function(lat, long, next){
var options = {
host: '1xx.xx.1xx.1x',
path: '/api/v1/geo,
method: 'GET'
};
var req = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
console.log(JSON.parse(msg));
});
});
req.on('error', function(err) {
// Handle error
});
req.write('data');
req.end();
var mis = 'hello';
next(null, mis);
}
At this moment I can get the Json and log it in the console. But I want to store the returned json in a variable so I could pass in the next() callback.
I tried to add a callback to the end event like:
exports.searchNear = function(lat, long, next){
....
.....
var req = http.request(options, function(res) {
.....
res.on('end', function(callback) {
console.log(JSON.parse(msg));
callback(msg);
});
});
....
req.end('', function(red){
console.log(red);
});
}
Thank you in advance.
The callback's name in your code should be "next":
var http = require('http');
exports.searchNear = function(lat, long, next) {
var options = {
host: '1xx.xx.1xx.1x',
path: '/api/v1/geo,
method: 'GET'
};
var req = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
});
res.on('end', function() {
console.log(JSON.parse(msg));
next(null, msg);
});
});
req.on('error', function(err) {
// Handle error
});
req.write('data');
req.end();
}
And then you should use your function like this:
searchNear(myLong, myLat, function (err, mesg) {
console.log('your JSON: ', mesg)
});
I may be misunderstanding your question but the obvious solution is to store your parsed json in a variable and pass the variable to next()
var parsed = JSON.parse(msg);

Sending data from Sails Service to a Controller

I'm writing a pretty basic HTTP request using SailsJS. I'm getting the data I want from the api that I'm calling, but I can't figure out how to pass it from my service back to the controller and eventually respond to the request with the data in the body.
Here's my controller:
module.exports = {
retrieve: function(req, res) {
var output = AccountService.retrieveAccountInfo();
console.log(output);
return res.send(output);
}
}
And here is my service that I'm calling.
module.exports = {
retrieveAccountInfo: function() {
var http = require('http');
var options = {
host: 'localhost',
port: 8280,
path: '/sample/account?id=1',
method: 'GET',
headers: {
'sample': 'header'
}
};
var req = http.request(options, function(res) {
var data = '';
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers) + '\n\n');
res.setEncoding('utf8');
res.on('data', function(chunk) {
console.log('BODY: ' + chunk);
data += chunk;
});
res.on('end', function() {
console.log('hit the end');
return JSON.stringify(data);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
}
}
I'm probably missing some basic JavaScript stuff here. I can get to the end callback and print "hit the end" as expected, but I can't get the data returned to the controller.
the method you're using in your service is an asynchronous method, you can modify them like following
module.exports = {
retrieve: function(req, res) {
AccountService.retrieveAccountInfo(function(error, output) {
console.log(output);
return res.send(output);
});
}
}
service - use callback method
module.exports = {
retrieveAccountInfo: function(callback) {
var http = require('http');
//.....
res.on('end', function() {
console.log('hit the end');
callback(null, JSON.stringify(data));
});
//.....
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
callback(e); //error
});
req.end();
}
}

How to get the result inside callback function in javascript?

If I want to write the result inside callback function to response, but I can't access the res variable in the function, and also I can't access the result outside the function.
So how to pass value between inside and outside?
var http = require('http');
var url = require('url');
http.createServer
(
function (req, res)
{
var output='';
res.writeHead(200, {'Content-Type': 'text/plain'});
//The url we want is: 'www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
console.log(str);
//output+=str; //get result
});
}
http.request(options, callback).end();
//output+=str; //get result
res.end(output);
}
).listen(80, '127.0.0.1');
ver2
var http = require('http');
var url = require('url');
http.createServer
(
function (req, res)
{
var output='';
res.writeHead(200, {'Content-Type': 'text/plain'});
//The url we want is: 'www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
res.write('inside');
});
}
http.request(options, callback).end();
res.write('outside');
res.end(output);
}
).listen(80, '127.0.0.1');
ver3
var http = require('http');
var url = require('url');
http.createServer
(
function (req, res)
{
res.writeHead(200, {'Content-Type': 'text/plain'});
//The url we want is: 'www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(res) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
res.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
res.on('end', function () {
res.write('inside');
//or
this.write('inside');
});
}
http.request(options, callback).end();
res.write('outside');
res.end();
}
).listen(80, '127.0.0.1');
ver4
var http = require('http');
var url = require('url');
http.createServer
(
function (req, res)
{
res.writeHead(200, {'Content-Type': 'text/plain'});
//The url we want is: 'www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
var str = '';
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
res.write('inside');
});
}
http.request(options, callback);
res.write('outside');
res.end();
}
).listen(80, '127.0.0.1');
You can't. The function that sets up the callback will have finished and returned before the callback executes. If it didn't, then the callback wouldn't be needed.
Do whatever work you need to do in the callback itself, not in the parent function.
I can't access the res variable in the function
You should be able to. It is still in scope.
(Although if you call end() on it before the callback runs, then breakage should be expected).

Categories

Resources