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;
};
Related
I am new to using async/await and having a couple issues.
I have the code below, which seems to not wait until the previous function is finished?
var url = require('url');
var path = require('path');
var https = require('https');
var request = require('request');
var url1 =
var url2 =
var url3 =
module.exports = async function (context, req) {
var call = await callUrl(context, url1);
context.log(call);
var call2 = await callUrl(context, url2);
context.log(call2);
var call3 = await callUrl(context, url3);
context.log(call3);
};
function callUrl (context, web) {
var requestUrl = url.parse(web);
const requestOptions = {
hostname: requestUrl.hostname,
path: requestUrl.path,
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
var request = https.request(requestOptions, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
var jsonData = JSON.parse(data);
return jsonData;
});
}).on('error', function(error) {
context.log("request error:", error);
return context.done();
});
request.end();
}
I am trying to get call to happen, then when it is finished call2, then when that is finished call3.
Can someone pinpoint why this does not occur? Currently, it hits all 3 pretty much asap, and each context.log is undefined presumably because the endpoints don't return anything. Each url is another azure function app API I have created.
There is nothing I am requiring to return from each call to use, I simply want them to finish before moving on the the next function.
Your callUrl method, which you call with await, needs to be either async itself or return a Promise. Why? because the work it does is itself asynchronous.
Here's your function adapted to use a Promise and return its actual value via the resolve() callback.
function callUrl (context, web) {
var requestUrl = url.parse(web);
const requestOptions = {
hostname: requestUrl.hostname,
path: requestUrl.path,
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
return new Promise(function (resolve,reject) {
var request = https.request( requestOptions, function( res ) {
var data = "";
res.on( 'data', function( chunk ) {
data += chunk;
} );
res.on( 'end', function() {
var jsonData = JSON.parse( data );
resolve( jsonData );
} );
} )
.on( 'error', function( error ) {
reject(error);
} );
request.end();
});
}
Notice that you use a POST operation with no body. That's a little unconventional.
We are using method called flask_api which has the parameter.
Our need is, we need to pass that parameter inside request.post
Can anyone please help as we are beginners in node.js
async flask_api(turnContext){
var res;
var fs = require('fs');
var request = require('request');
var formData = {image1: fs.createReadStream('D:/my_app/demo.png')}
var json_body = "" ;
var obj_value= ""
function initPromise(turnContext)
{return new Promise(function(resolve,reject)
{
console.log("print turn context",turnContext); //we are getting the value in turncontext
console.error('before post call...:1');
request.post({url:'http://127.0.0.1:5002/',formData: formData}, function(err, httpResponse, body)
{
if (err) {
console.log("response", reject(err));
return JSON.stringify(err);
}
else{
while(1==1){
if(body != undefined){
break;
}
}
json_body = JSON.parse(body);
resolve([json_body,turnContext]);//here we are not able to get the turncontext
}
});
})
}
Try using this:
var req = request.post({ url: 'http://127.0.0.1:5002/' }, (err, resp, body) => {
if (err) {
res.status(500).send(err);
} else {
res.send(resp);
}
});
var form = req.form();
form.append('file', fs.createReadStream('D:/my_app/demo.png'));
In your case:
async flask_api(turnContext){
var res;
var fs = require('fs');
var request = require('request');
var formData = {image1: fs.createReadStream('D:/my_app/demo.png')}
var json_body = "" ;
var obj_value= ""
var tempContext;
function initPromise(turnContext)
{return new Promise(function(resolve,reject)
{
tempContext = turnContext;
console.log("print turn context",tempContext); //we are getting the value in turncontext
console.error('before post call...:1');
request.post({url:'http://127.0.0.1:5002/',formData: formData}, (err, httpResponse, body) =>
{
if (err) {
console.log("response", reject(err));
return JSON.stringify(err);
}
else{
while(1==1){
if(body != undefined){
break;
}
}
json_body = JSON.parse(body);
resolve([json_body,tempContext]);//here we are not able to get the turncontext
}
});
})
}
Try this. Note that I refactored your code (how I would have done it).
Server (for test purposes)
var http = require('http');
var querystring = require('querystring');
var server = http.createServer().listen(8124);
server.on('request', function(request,response) {
if (request.method == 'POST') {
var body = '';
// append data chunk to body
request.on('data', function (data) {
body += data;
});
// data transmitted
request.on('end', function () {
var post = querystring.parse(body);
console.log(post);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(JSON.stringify('body\n'));
});
}
});
console.log('server listening on 8124');
Client
function initPromise(turnContext) {
var res;
var fs = require('fs');
var request = require('request');
var formData = {image1: "hello"}
var json_body = "" ;
var obj_value= "";
return new Promise(function(resolve,reject) {
console.log("print turn context",turnContext); //we are getting the value in turncontext
console.error('before post call...:1');
request.post({url:'http://localhost:8124/',formData: formData}, function(err, httpResponse, body) {
if (err) {
reject(err);
}
else{
if (body != undefined) {
json_body = JSON.parse(body);
resolve([json_body,turnContext]); //here we are not able to get the turncontext
} else {
reject('body undefined');
}
}
});
});
}
async function flask_api(turnContext) {
var result = initPromise(turnContext);
console.log("result", result);
result.then(
// fulfillment
function (val) { //this is where you get the value passed to resolve()
console.log(val);
}).catch(
//log the rejection reason
(reason) => {
console.error(reason);
}
);
}
flask_api({test: 'hello'});
The result on the client side is:
print turn context { test: 'hello' }
before post call...:1
result Promise { <pending> }
[ 'body\n', { test: 'hello' } ]
Note:
That line of code return JSON.stringify(err); isn't necessary. The callback in a promise is not expecting any return unless you want to use it for flow control purposes.
if body is indeed undefined, you will have an infinite loop.
Try using this:
This will work for the latest node.js versions.
async initPromise(turnContext)
{
var res;
var fs = require('fs');
var request = require('request');
var formData1 = {image1: "Hello"};
var path = require('path')
var base_dir=path.dirname(path.dirname(__filename))
console.log(path.join( base_dir, "resource", "output.png"));
var image_name = path.join( base_dir, "resource", "output.png")
var formData = { image1: fs.createReadStream(image_name) };
var json_body = "" ;
var obj_value= "";
return await new Promise(function(resolve,reject)
{
console.log("pls work",turnContext);
//\var turnContext1 = turnContext;
//\console.log(typeof(turnContext));
console.error('before post call...:1');
request.post({url:'http://127.0.0.1:5002/',formData: formData}, (err, httpResponse, body) =>
{
console.log("formdata....body....",formData);
console.log("inside request post");
if (err) {
reject(err);
}
else{
if (body != undefined) {
json_body = JSON.parse(body);
console.log("response inside", json_body);
resolve([json_body,turnContext]); //here we are not able to get the turncontext
} else {
reject('body undefined');
}
}
});
});
}
async flask_api(turnContext) {
var result = await this.initPromise(turnContext);
console.log("result", result);
console.log("result1", result[0]);
console.log("result2", result[1]);
}
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.
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.
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);