how to get readStream with thunk in koa ? - node.js

I want to pipe a request in a koa controller, It's work:
var s = require('through2')();
var req = http.request(url, function(res) {
res.pipe(s);
})
req.end(null);
s.on('close', function() {
console.log('has close');
});
this.body = s;
But with thunk , it seems to be not work.
var s = stream();
yield thunk(url, s);
this.body = s;
Here is the thunk:
var thunk = function (url, s) {
return function(callback) {
var req = http.request(url, function(res) {
res.pipe(s);
});
s.on('close', function() {
callback(null, null);
console.log('req inner close');
});
req.end(null);
}
}

Use a promise for this (return a promise, not a thunk). Off the top of my head, so you may need to play around with it:
function run(url, s) {
return new Promise(function(resolve, reject) {
var req = http.request(url, function(res) {
res.pipe(s);
res.on('end', function() {
req.end();
});
});
req.on('error', function(err) {
return reject(err);
});
s.on('close', function() {
console.log('req inner close');
return resolve();
});
});
}
Then:
yield run(url, s);

Related

how to get the data from http.get

I have created a NodeJS server and created promises for the HTTP.get method and calling the get method function in created server but it showing error options.uri
var http = require('http');
var request = require('request');
var rese = null;
function initialize() {
var options = {
host: 'httpbin.org',
path: '/json',
};
return new Promise(function (resolve, reject) {
request.get(options, function (err, res, body) {
if (err) {
reject(err);
} else {
resolve(JOSN.parse(body));
}
/** res.on("data", function(chunk) {
//console.log("BODY: " + chunk);
result=chunk;
});*/
})
})
}
http.createServer(function (req, res) {
if (req.url == '/my') {
/**result=res.on("data", function(chunk) {
console.log("BODY: " + chunk);
});*/
var initializePromise = initialize();
initializePromise.then(function (res) {
rese = result;
console.log("Initialized user details");
// Use user details from here
console.log(userDetails)
}, function (err) {
console.log(err);
});
//res.end(result);
}
else {
res.end('please find the correct path');
}
}).listen(2000);
error:options.uri is a required argument
Your get method should include uri, The request api get call structure is as follows,
request.get("http://bin.org/json", options, function (err, res, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
/** res.on("data", function(chunk) {
//console.log("BODY: " + chunk);
result=chunk;
});*/
})
Try to make this changes, it will work

var function calling for unknown reason

I have the code below, and it seems to call the var promiseFeedback is called and I don't know why... This means it is called even when an error occurs when I create document. Whereas is should only be called if there is no err in the createDocument.
Is anyone able to clear up why?
if (json) {
createDocument(documentUrl, context, json, function(res){
var promiseFeedback = callFB (context, res);
var collection = `mydb`
client.createDocument(collection, res, (err, result) => {
if(err) {
context.log(err);
return context.done();
} else {
Promise.all([promiseFeedback]).then(function(results){
context.log("promiseFeedback: " + results[0]);
context.done();
});
}
});
});
}
function callFB(context, res) {
return new Promise((resolve, reject) => {
var requestUrl = url.parse( URL );
var requestBody = {
"id": res.id
};
var body = JSON.stringify( requestBody );
const requestOptions = {
hostname: requestUrl.hostname,
path: requestUrl.path,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
}
};
var request = https.request(requestOptions, function(res) {
var data ="";
res.on('data', function (chunk) {
data += chunk
});
res.on('end', function () {
resolve(true);
})
}).on('error', function(error) {
context.log("request error:", error);
resolve(false);
});
request.write(body);
request.end();
});
}
var promiseFeedback = callFB (context, res);
This statement executes callFB immediately, not just assigns another name to the promise. This promise callFB is out of the callback(scope) of err and Promise.all([promiseFeedback]), it runs no matter what the result of client.createDocument is.
To fix this:
Remove var promiseFeedback = callFB (context, res); and change Promise.all([promiseFeedback]) to callFB(context, res). You don't need to use Promise.all as you only have one promise to resolve.
Or you can just move var promiseFeedback = callFB (context, res); into else segment.

Promises then/catch

I have the following code:
return requestAsync({
method: 'GET',
url: 'https://' + servers[num - 1] + ':8033/version.txt'
}).then().catch()
I tried throwing an error in the then handler but that didn't work
If a condition is not met in the then handler, I want throw an error that the catch handler handles. How can I get that done?
Code:
var P = require('bluebird');
var defer = function () {
var resolve, reject;
var promise = new P(function () {
resolve = arguments[0];
reject = arguments[1];
});
return {
resolve: function () {
resolve.apply(null, arguments);
return promise;
},
reject: function () {
reject.apply(null, arguments);
return promise;
},
promise: promise
};
};
var pool = {maxSockets: Infinity};
var requestAsync = function (options) {
options.pool = pool;
options.timeout = 60000;
options.rejectUnauthorized = false;
options.strictSSL = false;
var deferred = defer();
var r = request(options, function (err, res, body) {
if (err) {
return deferred.reject(err);
}
deferred.resolve(res, body);
});
deferred.promise.req = r;
return deferred.promise;
};
return requestAsync({
method: 'GET',
url: 'https://' + servers[num - 1] + ':8033/version.txt'
}).then(function (response) {
throw new Error('Server is not taken');
}).catch(function (err) { });
You can manually throw the error:
requestAsync({
method: 'GET',
url: 'https://' + servers[num - 1] + ':8033/version.txt'
})
.then(function () {
throw new Error("Catch me")
}))
.catch(function (error) {
console.error(error)
})
jsbin: https://jsbin.com/dewiqafaca/edit?html,js,console,output
Just use throw to generate a standard JavaScript exception in your then function and it should invoke the function in your catch block with whatever value you provide as the argument.

Using Q library for HTTP api response testing in nodejs

how to use Q to make it wait until previous response has come from the server.
What I am looking to do here is compare the response from test server and production server for the same request.
I get the responses back from both the servers, but unable to compare them since the assert statement is executed before the response comes back.
Any one know what I am doing wrong. heres the code.
var Q = require('q');
var path='';
var prodResponse = '';
var tstReponse = '';
Q.fcall(readFile())
.then(secondFunction())
.then(thirdFunction())
.then(function(){
console.log("prodResponse: "+prodResponse);
console.log("tstResponse: "+tstResponse);
assert.strictEqual(prodResponse, tstResponse)
})
.catch(function(){
console.log('error occurred');
})
.done();
function readFile(){
fs.readFile('hostname.json', function (err, data) {
if (err) return console.error(err);
path = JSON.parse(data);
return JSON.parse(data);
});
}
function secondFunction(){
var prodOptions = {
hostname: 'somehostname.com',
port: 80,
path: "/path?"+path.path,
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
auth : ''
};
return http.request(prodOptions, function(res) {
console.log('Prod');
res.setEncoding('utf8');
res.on('data', function (chunk) {
prodResponse = chunk;
return chunk;
});
res.on('end', function() {
console.log('No more data in response.');
})
}).on('error', function(e) {
console.log('problem with request: ' + e.message);
}).end();
}
function thirdFunction(){
// same a second, only difference is the response http.
}
There is multiple errors in your code
Q.fcall(readFile())
Your q variable is q and not Q. So this line will crash because Q is undefined (javascript is case sensitive).
Then, readFile doesn't return any promise (in fact, it returns nothing). So the q library can't use anything to wait the end of any asynchronous work. The then callbacks will be fired immediatly.
You can use Q.ninvoke to make your readFile function return a promise, and you can use Q.defer to create and return a promise from your secondFunction:
var Q = require('q');
var path='';
var prodResponse = [];
var tstReponse = '';
readFile()
.then(secondFunction())
.then(thirdFunction())
.then(function(){
console.log("prodResponse: "+prodResponse);
console.log("tstResponse: "+tstResponse);
assert.strictEqual(prodResponse, tstResponse)
})
.catch(function(){
console.log('error occurred');
})
.done();
function readFile(){
return Q.ninvoke(fs, 'readFile', 'hostname.json').then(function (data) {
path = JSON.parse(data);
return path;
}, function (err) {
console.error(err);
});
}
function secondFunction(){
var prodOptions = {
hostname: 'somehostname.com',
port: 80,
path: "/path?"+path.path,
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
auth : ''
};
var defer = Q.defer();
var chunks = [];
http.request(prodOptions, function(res) {
console.log('Prod');
res.setEncoding('utf8');
res.on('data', function (chunk) {
chunks.push(chunk);
});
res.on('end', function() {
console.log('No more data in response.');
prodResponse = chunks.join('');
defer.resolve(prodResponse);
})
}).on('error', function(e) {
console.log('problem with request: ' + e.message);
defer.reject(e);
}).end();
return defer.promise;
}
function thirdFunction(){
// same a second, only difference is the response http.
}

Promise not getting resolved while sending http request

I am calling func2(which should return promise) but promise is not getting resolved.Am I resolving promise wrongly or is there any other problem.Please let me know what is the problem in following code?
function func1() {
func2().then(function (data) {
console.log(data);
})
}
var func2 = function () {
var d = q.defer();
var postRequest = {
host: "abc",
path: "/xyz",
};
var buffer = "";
var req = http.request( postRequest, function( res ) {
var buffer = "";
res.on( "data", function( data ) {
console.log("data\n");
buffer = buffer + data;
});
res.on( "end", function( data ) {
d.resolve(data);
return d.promise;
});
});
console.log('after req');
req.write(body);
req.end();
};
You need to return the promise at the very end of the function. Try
function func1() {
func2().then(function (data) {
console.log(data);
}).catch(function (error) {
// Handle any error from all above steps
console.log("Got error:" + error);
})
.done();
}
var func2 = function () {
var d = q.defer();
var postRequest = {
host: "abc",
path: "/xyz",
};
var buffer = "";
var req = http.request( postRequest, function( res ) {
var buffer = "";
res.on( "data", function( data ) {
console.log("data\n");
buffer = buffer + data;
});
res.on( "end", function( data ) {
d.resolve(buffer);
});
res.on( "error", function( err ) {
d.reject(err);
});
});
console.log('after req');
req.write(body);
req.end();
return d.promise;
};

Resources