Node Js HTTP response crashes when response length exceeds 16101 - javascript

I am using Node JS HTTP request. When my response length exceeds 16101 , it truncates my response. And I recieve limited response like this:
{"id_user":"133696"},{"id_u
This is not a chunked response, its only comes once. I want to recieve the whole response instead of truncated .
My Node version is v0.10.36.
Here is my code:
var https = require('https');
var querystring = require('querystring');
postData.format = 'json';
postData.apikey = 'abcd';
jsonObject = querystring.stringify(postData);
var postheaders = {
'Content-Type' : 'application/x-www-form-urlencoded',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
if(callMethod == undefined){
callMethod = 'POST';
}
var optionspost = {
host : this.host,
port : this.port,
path : this.path,
method : callMethod,
headers : postheaders
};
var reqPost = https.request(optionspost, function(res) {
res.setEncoding('utf-8');
res.on('data', function(responseData) {
//---->>> responseData containes truncated response
if(callFunction != undefined && callFunction != null && callFunction != ''){
callFunction(responseData, relatedData);//****** calling success function ****
}
});
res.on('end', function() {
});
});
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
console.error(e);
});

Your code is expecting the data event only once, but Node can fire it more than once. In fact, it can fire it as many times as it damn pleases.:) Every time a data event is emitted, another part of the data is provided to you. You know that there is no more data to be consumed when the end event is fired - that's where you should process the data and/or call your callbacks.
Since the response is basically a readable stream, have a look at the data event for Readable Stream.

Related

JSON url parse returns NaN in Node.js

I have created a URL Shortener web service, which returns JSON, if correct parameters (url) is passed.
Now, since I am learning Node.js, I am trying to create a Node.js wrapper for parsing the data and printing them in console (for now).
I am using http and request module for parsing the JSON data which I received from the url response.
This is my code that prints the data :
var request = require('request');
var http = require('http');
var url = process.argv[2];
var apiUrl = "http://shtr.ml/stats-api.php?url=" + url;
http.get(apiUrl,function(res){
var body = '';
res.on('data',function(chunk)
{
body += chunk;
});
res.on('end',function(){
const resp = JSON.parse(body);
console.log(JSON.stringify(resp));
if(resp.message.toString() == "Success")
{
console.log("Short URL : ",resp.short-url);
console.log("Long URL : ",resp.long-url);
console.log("Creation Date : ",resp.created);
console.log("Total Clicks : ",resp.clicks);
}
else
{
console.log("Stats Error !!");
}
});
}).on('error',function(e){
console.log("Got an error ",e);
});
Now, following is my code output :
C:\node-shtr-module>node index.js http://shtr.ml/ZVFWdk
{"message":"Success","short-url":"http://shtr.ml/ZVFWdk","long-url":"https://github.com/beingadityak/dot-net-mysql","created":"2016-09-27 22:58:06","clicks":"21"}
Short URL : NaN
Long URL : NaN
Creation Date : 2016-09-27 22:58:06
Total Clicks : 21
Why is the resp.short-url returning NaN even though the JSON contains the URL ? Please help.
As always, thanks in advance.
access it using
resp['short-url'] and resp['long-url']

Delay is socket.io event?

I created an ajax call to the IMBd database
// API Key
key = "4dba72b2-7558-4c0f-bd18-9ffcb0999c4e";
// Url
mainUrl = "http://api.myapifilms.com/imdb/top?token="+ key +"&format=json&data=0&start=1&end=250";
// API Call
var request = require('request');
request(mainUrl, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Storing data in an object
var obj = JSON.parse(body), //JSON Parser
movieArray = obj.data.movies, //Creating Array
item = movieArray[randomMovieRank]; //Setting random movie variable
itermArray = [item.ranking,item.title,item.year];
console.log(itermArray);
io.sockets.emit("serverAnswer", {ranking: itermArray[0], title: itermArray[1], year: itermArray});
}
});
return false;
Followed up by:
socket.on("serverAnswer", function(data){
console.log(data.title);
});
The socket.on is called on the client side. The problem I am having is that it is pulling through the data very slowly if at all. The API is working as it is console logging correctly in terminal. But client side it sometimes pulls through ad sometimes doesnt. Is there something I am doing wrong?
EDIT:
Added pastebin: http://pastebin.com/TYHsqBmK
When you invoke the emit method, your client is not guaranteed connected,you can trigger the ajax event after the client connected or emit specified messages,such as
the server:
io.on('connection',function(socket){
if(movies !== null)
{
socket.emit("serverAnswer", {movies:movies});
}
else{
//1.ajax request IMDB resource
//2.set movies variables
//3.emit message
}
});
the client:
socket.on("serverAnswer", function(data){
console.log(data);
});

alternative to through2-map in node.js [related to learnyounode]

Problem i am solving:
Write an HTTP server that receives only POST requests and converts incoming POST body characters to upper-case and returns it to the client.
Your server should listen on the port provided by the first argument to your program.
My Solution
var http = require('http');
var map = require('through2-map')
http.createServer(function(request,response){
if (request.method == 'POST'){
request.pipe(map(function (chunk) {
return chunk.toString().toUpperCase();
})).pipe(response);
}
}).listen(process.argv[2]);
Can i implement is without using through2-map ?
My crippling solution which doesn't work:
request.on('data',function(data){
body += data.toString();
console.log(body);
});
request.pipe(body.toUpperCase()).pipe(response);
Can i do the real hard way ?
In the 2nd snippet, body.toUpperCase() will act immediately before any of the 'data' events have actually occurred. The call to .on() only adds the event handler so it will be called, but doesn't yet call it.
You can use the 'end' event, along with 'data', to wait for all data chunks to be received, ready to be uppercased:
request.on('data', function (data) {
body += data.toString();
});
request.on('end', function () {
response.end(body.toUpperCase());
});
Note: Be sure that body is being declared and assigned an initial value:
var body = '';
response.on('data', ...);
// ...

Http request document head

I need to get the document title.
so I try to send request, and paser the response html to get title.
example (via nodejs module request):
request.get("http://www.google.com", function(err, res, body) {
var title = body.match(/<title>(.*?)</title>/g)[1];
})
but when the document is particularly large. the request is slowly.
Is there a way to get document title quickly? Please suggest. Thanks.
Request can give you stream of decompressed data as it is received: http://github.com/request/request#examples (2nd example)
You could keep appending the data received in a buffer, and checking whether it has your desired content yet ("</title>"). As soon as you get it, you could get your title and ignore the rest of the buffer in the stream.
var request = require('request');
var buffer = '';
var flag = 0;
request({
method: 'GET',
uri: 'http://www.google.com',
gzip: true
}).on('data', function(data) {
if (buffer.indexOf('</title>') == -1)
buffer += data;
else done();
});
function done() {
if (flag) return;
flag++;
var title = buffer.match(/<title>(.*?)<\/title>/)[1];
console.log(title);
}

NodeJS HTTP request POST ERROR socket hang up

Hi I'm having problems to perform HTTP request on NodeJS given a larger number array of json object. The request works fine given small array of json object. However, if I try to increase the size array of json, I received Error: socket hang up {"error":{"code":"ECONNRESET"}}. Is it required to perform multiple write? Or is it something wrong going on at the other end?
Thanks in advance for taking your time here!
// data is a json object
var post_data = JSON.stringify(data);
var buf = new Buffer(post_data);
var len = buf.length;
var options = {
hostname: address,
port: port,
path: pathName,
method: 'PUT',
headers: {
'Content-Type':'application/json',
'Content-Length': len,
'Transfer-Encoding':'chunked'
}
};
// http call to REST API server
var req = restHttp.request(options, function(res) {
console.log('server PUT response received.');
var resData = '';
res.on('data', function(replyData) {
// Check reply data for error.
console.log(replyData.toString('utf8'));
if(replyData !== 'undefined')
resData += replyData;
});
res.on('end', function() {
callback(JSON.parse(resData));
});
});
req.write(buf);
req.end();
You can stream the request body.
If the data in buf was in a readable stream then you can just do buf.pipe(req).
For example, if the current directory contains a file data.json with the JSON you can do
var buf = fs.createReadStream(__dirname + '/data.json');
to create a ReadStream object. Then you can pipe this to you req
buf.pipe(req);
The pipe command will call req.end once its done streaming.

Categories

Resources