Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js. Http.get() function is not responding.

The http.get() function inside http.createServer is not responding.

I wrote a small snippet to retrieve JSON data when a user send a request to the server. Here is my code.

var http = require('http');
var x = '';
http.createServer(function (request,response) {
    http.get({
        host:'query.yahooapis.com',
        path:'/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22)&format=json&env=store%3A%2F%2Fdata tables.org%2Falltableswithkeys&callback=cbfunc'
    }, function(res){
        res.on('data',function(d){
            x+=d.toString();
            console.log(d.toString());
        })
    });

    response.writeHead(200, {'Content-Type':'text/plain'})
    var l = JSON.parse(x.substring(7,x.length-2));
    response.end(l.query.results.quote[0].symbol + '');
}).listen(8080);

I am getting the error:

undefined:0

SyntaxError: Unexpected end of input
    at Object.parse (native)
    at Server.<anonymous> (C:\Users\Lenovo\Documents\fetch.js:18:12)
    at Server.emit (events.js:70:17)
    at HTTPParser.onIncoming (http.js:1491:12)
    at HTTPParser.onHeadersComplete (http.js:102:31)
    at Socket.ondata (http.js:1387:22)
    at TCP.onread (net.js:354:27)

As far as I think. Error is due to x='' is not a json so its throwing an error. But when sending a request by calling localhost:8080 it should show some json text on console instead of error. My aim is to parse the stock quotes in real time so i made a get request when request come and set its result to response.

i tried one more snippet for getting the data

var http = require('http');
var x = '/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22)&format=json&env=store%3A%2F%2Fdata tables.org%2Falltableswithkeys&callback=cbfunc';

http.get({
    host: 'query.yahooapis.com', 
    path: ''
},function(res){
        res.on('data',function(d){
        x+=d.toString();
        console.log(d.toString());
    })
});
http.createServer(function(request,response){
    response.writeHead(200,{'Content-Type':'text/plain'})
    var l=JSON.parse(x.substring(7,x.length-2));
    response.end(l.query.results.quote[0].symbol+'');
}).listen(8080);

It's working fine showing json text on console but I think I will get the data for once when I deployed it on server not when user is requesting the data. How can I solve the error?

like image 896
Ritesh Mehandiratta Avatar asked Jul 21 '26 17:07

Ritesh Mehandiratta


1 Answers

node.js is asynchronous. This means that http.get will return at some point. You send of a http.get request and then immediatly try to manipulate the x that your only writing to once the http.get request finishes.

Basically x === '' when your calling JSON.parse because the http.get callback doesn't fire until later.

var http = require('http');
var x = '';
http.createServer(function(request, response) {
    http.get({
        host: 'query.yahooapis.com',
        path: '/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=cbfunc'
    }, function(res) {
        res.on('data', function(d) {
            x += d.toString();
            console.log(d.toString());
        });

        res.on('end', next);
    });

    function next() {
        response.writeHead(200, {
            'Content-Type': 'text/plain'
        })

        var l = JSON.parse(x.substring(7, x.length - 2));
        response.end(l.query.results.quote[0].symbol + '');
    }
}).listen(8080);

The important thing here is to wait until the http.get call has finished until you send the json response.

like image 76
Raynos Avatar answered Jul 23 '26 06:07

Raynos