Node.JS Request Module Callback Not Firing - javascript

I'm running this code using the request module for node.js
var hsKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
var hsForm = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
var hsHost = "https://docs.google.com/"
var url = hsHost + "forms/d/" + hsForm + "/formResponse"
var form = {
"entry.129401737": pointsAvg,
"entry.2000749128": hiddenNeurons,
"submit": "Submit",
"formkey": hsKey
};
request.post({
url: url,
form: form
}, function (err, res, body) {
console.log("Sent data");
});
I have tried running the above code just using standard Node.JS libraries, to no avail. The callback function is never fired and the request doesn't go through. I don't know why.

I believe I've found the answer to my own problem. The issue seems to be that I'm not allocating any time in the Node.js event loop to allow the request to be executed.

Have a look at this question:
your code should look something like
var hsKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var hsForm = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var hsHost = "https://docs.google.com/"
var url = hsHost + "forms/d/" + hsForm + "/formResponse"
var form = {
"entry.129401737": pointsAvg,
"entry.2000749128": hiddenNeurons,
"submit": "Submit",
"formkey": hsKey
};
request.post({
url: url,
form: form
}, function (response) {
response.setEncoding('utf8');
response.on('data', function(chunk){
//do something with chunk
});
});
The data event should get fired on receiving a response.
So if you read the docs for the request module at npm
request
.get('http://google.com/img.png')
.on('response', function(response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type']) // 'image/png'
});
There is a response event that should get fired.

I ran into this as well. I ended up creating a separate js file containing only the request, without the describe and it methods, and running it with 'mocha mynewbarebonesreq.js'. suddenly I could see that there was an exception being thrown and swallowed by mocha (with the standard reporter, spec).
I finally installed and enabled mocha_reporter which shows the exceptions
now it looks like this:
describe('CMSLogin', function () {
it('should log in as user ' + JSON.stringify(USER_PASS), function (done) {
request({
url: "http://cms.lund.multiq.com:3000/api/CMSUsers/login",
method: "POST",
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
json: false,
body: JSON.stringify(USER_PASS)
}, (err, res, body) => {
var parsedBody = JSON.parse(body);
this.token = parsedBody.id;
console.log(this.token)
assert.equal(USER_PASS.userId, parsedBody.userId);
assert.doesNotThrow(() => Date.parse(parsedBody.created));
if (err) { done.fail(err); }
done();
});
});
}

Related

Firebase Function using request library not firing

Almost there, but for some reason my HTTP post request isn't firing and eventually the function timesout. Completely beside myself and posting my code to see if anyone picks up on any noob moves that I'm completely missing. NOTE: the database write completes so I'm assuming that the HTTP Post request isn't firing, is that a safe assumption? Or JS is a different beast?
exports.stripeConnect = functions.https.onRequest((req, res) => {
var code = req.query.code;
const ref = admin.database().ref(`/stripe_advisors/testing`);
var dataString = `client_secret=sk_test_example&code=${code}&grant_type=authorization_code`;
var options = {
url: 'https://connect.stripe.com/oauth/token',
method: 'POST',
body: dataString
};
function callback(error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body);
}
}
request(options, callback);
return ref.update({ code: code });
});
I understand that you want to POST to https://connect.stripe.com/oauth/token by using the request library and, on success, you want to write the code value to the database.
You should use promises, in your Cloud Function, to handle asynchronous tasks. By default request does not return promises, so you need to use an interface wrapper for request, like request-promise
Therefore, the following should normally do the trick:
.....
var rp = require('request-promise');
.....
exports.stripeConnect = functions.https.onRequest((req, res) => {
var code = req.query.code;
const ref = admin.database().ref('/stripe_advisors/testing');
var dataString = `client_secret=sk_test_example&code=${code}&grant_type=authorization_code`;
var options = {
url: 'https://connect.stripe.com/oauth/token',
method: 'POST',
body: dataString
};
rp(options)
.then(parsedBody => {
return ref.update({ code: code });
.then(() => {
res.send('Success');
})
.catch(err => {
console.log(err);
res.status(500).send(err);
});
});

Node JS integration with spark job server

I'm trying to call spark job server API from node js. The API which is the python egg file does provide the count of nulls from the file. So once I call the API from the node, it is reaching the SJS server and the job starts which triggers res.on('data') event and soon after that, it triggers res.on('end') as well before the job finishes it's execution and returns the result. So due to this, I am not able to get the data once the job completes.
Below is the code snippet, Please let me know what is the mistake done here.
var postData = {
'input': {
'strings': {
'file': 'file path to be passed'
}
}
};
var options = {
hostname: 'localhost',
port: 8090,
path: '/jobs?appName=my_ml_job&classPath=my_py_package.NullCheck.nullcheck&context=py-context',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(JSON.stringify(postData))
}
};
var post_req = Http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Response: ' + chunk);
});
res.on('end', () => {
return{
'STATUS': 'FINISHED'
}
});
});
post_req.on('error', e => {
rj(e);
});
// post the data
post_req.write(postData);
post_req.end();

async.js Ordering of functions

So I'm having trouble getting one javascript function to finish before the next one starting. I've spent quite a lot of time trying to use callback methods described on other stackoverflow posts. I could get simple examples that used timeouts to work but couldn't get it to work with my API request. I stumbled upon async.js and thought that perhaps using async.series would be a good idea to get my two functions to perform one after another. So I tried this approach, however I still seem to be having the problem where the first function takes a bit longer to execute (which is fine) but the execution process moves past this function instead of waiting for it to end. I feel I have a misconception of some sort since I have tried several methods but to no avail.
What is strange is, is that that when running server.js, it goes into the first function but then it leaves the async.series() function even before the request is finished. When I print inside of tokenReq(), I can see that the request was successful as a token code is returned successfully however this happens to late as execution has moved on. The output is shown below.
server.js:
var access_code;
async.series([
function() {
access_code = queries.data.tokenReq(code);
console.log("Finished inside function 1");
},
function() {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
}
],
function(err, access_code) {
});
console.log("Outside");
queries.js:
tokenReq: function(code) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return access_token;
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return "error";
}
});
},
Output:
Finished inside function 1
Outside
INSIDE FUNCTION REQUEST, Token: 8Swhd.......
You missed a major point here. Since node.js is asynchronous there should not be a way to know when a function completes its execution. That is why we specify callbacks so that the invoking function knows whom to call when it finishes its execution. Once you have functions with callbacks, you can enforce series/parallel/waterfall behavior with async module.
tokenReq: function(code, cb) {
var tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
var form = {
code: code,
client_id: "__ID__",
redirect_uri: "__Site__/",
grant_type: "authorization_code",
client_secret: "__Secret__",
};
var formData = querystring.stringify(form);
var contentLength = formData.length;
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded'
},
uri: tokenUrl,
body: formData,
method: 'POST'
}, function (error, response, body) {
if (error != "null") {
var access_token = JSON.parse(body).access_token;
console.log("\n INSIDE FUNCTION REQUEST, Token: " + access_token + " \n");
return cb(null, access_token);
} else {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
return cb(new Error("whatever"));
}
});
},
Now, you can use the callback inside server.js
var access_code;
async.series([
function(cb) {
return queries.data.tokenReq(code, cb);
},
function(access_code, cb) {
console.log("\n Starting function 2 \n");
if (access_code === "error") {
res.json("An error has occured");
} else {
var response = queries.data.messagesReq(access_code);
res.json(response);
}
// do whatever you want after this
return cb();
}
],
function(err, access_code) {
if (err) {
console.log(err);
}
// wrap your logic around a function and call the correspoding callback here
});

Python REST API call equivalent in Node.js

I've been recently trying to communicate with the UniProt API. As I am starting with Node.js, I have some initial problems, namely:
I am trying to conver this python request:
import urllib,urllib2
url = 'http://www.uniprot.org/uploadlists/'
params = {
'from':'ACC',
'to':'P_REFSEQ_AC',
'format':'tab',
'query':'P13368 P20806 Q9UM73 P97793 Q17192'
}
data = urllib.urlencode(params)
request = urllib2.Request(url, data)
contact = "" # Please set your email address here to help us debug in case of problems.
request.add_header('User-Agent', 'Python %s' % contact)
response = urllib2.urlopen(request)
page = response.read(200000)
To node.js.
My attempt:
var params = {
'from':'ACC',
'to':'P_REFSEQ_AC',
'format':'json',
'query':'P13368 P20806 Q9UM73 P97793 Q17192'
}
var post_data = querystring.stringify(params);
var url = 'http://www.uniprot.org/uploadlists/'
var options = {
uri: url,
qs: post_data,
method: 'POST'
};
urllib.request(options, function (err, data, res) {
if (err) {
throw err; // you need to handle error
}
console.log(data.toString())
cb("test") // this doesnt currently matter
});
What am I doing wrong? Thank you.
Using node-rest-client can help you achieve what you are trying.
npm i node-rest-client --save
I believe you have a starter project for nodejs which contains package.json.
var Client = require('node-rest-client').Client;
var client = new Client();
var args = {
data: {
'from': 'ACC',
'to': 'P_REFSEQ_AC',
'format': 'json',
'query': 'P13368 P20806 Q9UM73 P97793 Q17192'
},
headers: {
"Content-Type": "application/json"//use the header that you need
}
};
client.post("http://www.uniprot.org/uploadlists/", args, function(data, response) {
// parsed response body as js object
console.log(data);
// raw response
console.log(response);
});

How to call a function only after getting response from restcall node js

I have one request.post call and another function.Where I need to pass the response of restcall as paramaters to the function.
The current issue which Iam facing here is that the function is getting called even before i get response from the rest call and null values are getting passed.I know that we need to use some callabcks for this issue.But I dont know how to do it.can someone help.
app.post('/verifycreds',function(req,res) {
var reqdata = req.body;
var data = {};
data.custid = reqdata.custid;
request.post({
url:'https://database.mybluemix.net/verifycredentials',
headers:{
'Content-Type':'application/json'
},
body:data,
json:true
}, function(err,response) {
verifycreds(response.body);
});
function verifycreds(data) {
if((datareq.customerid === data.customerid ) && (datareq.password == data.password)){
res.send("valid");
} else {
res.send("invalid");
}
}
So how can I call verifycreds function only after I get response from the request .post call..Any help!
Your callback is valid, the problem in callback parameters. It should be defined with three parameters:
error
response
body
So correct code is:
request.post({
url: 'https://database.mybluemix.net/verifycredentials',
headers: {
'Content-Type': 'application/json'
},
body: data,
json: true
}, function(err, res, body) {
// TODO: process possible errors
// if (err) { ...
verifycreds(body);
});

Categories

Resources