Alternative for .then() after request() - node.js

I'm new to NodeJS. I have an asynchronous function
request({url: 'url',json: true}, function (error, response, body) {});
I want to call a function only after this function is invoked. I can't call a .then() here. What are the other alternatives for this situation?

You could try something like this
return new Promise(resolve => {
request({
url: "",
method: "",
headers: {},
json: true
}, function (error, response, body) {
if(!error)
resolve(body);
})
}).then(value => {
// process value here
})

Just pass it as your callback function:
function callback (err, res, body) {
// Do what needs to be done here.
}
request({ url: 'url', json: true, someParam: true }, callback);
At the beginning of your callback function, check if err exists and if so, handle the error.
This article might help you.
You can only call then if your asynchronous function returns a Promise. But before you get into Promises, you should know the basics about Node.js.

Related

How to return the response of Post request from a function in NodeJS?

I have a function in my project that processes most of my API requests (see simplified draft below)
function sendRequest(){
var reqbody;
var resp;
reqbody = unimportantRandomFunction();
request.post({
headers: { 'content-type' : 'application/xml',
'accept' : 'application/xml'},
url: process.env.APIURL,
body: reqbody
}, function(error, response, body){
resp = convert.xml2js(body, {compact:true});
});
return resp;
}
The problem I am facing is that request.post is asynchronous and by the time I get the response, an undifined value has already been returned.
I tried experimenting with promises (something I am entirely new to) but obviously I can't place my return in a .then block either because that return will not belong to the sendRequest function (correct me if I'm wrong).
Any ideas where I could put my return statement to make it work, that is wait for the value of "resp" to be assigned?
How about this modification? Please think of this as just one of several possible answers.
Promise is used sendRequest(). And the response value is retrieved in the async function. At the following modified script, at first sample() is run. And sendRequest() is run, then the response value is retrieved at console.log(res).
Modified script:
function sendRequest() {
return new Promise((resolve, reject) => {
var reqbody;
var resp;
reqbody = unimportantRandomFunction();
request.post(
{
headers: {
"content-type": "application/xml",
accept: "application/xml"
},
url: process.env.APIURL,
body: reqbody
},
function(error, response, body) {
if (error) reject(error);
resp = convert.xml2js(body, { compact: true });
resolve(resp);
}
);
});
}
async function sample() {
const res = await sendRequest().catch(err => console.log(err));
console.log(res);
}
sample(); // This function is run.
References:
Promise
async function
If I misunderstood your question and this was not the direction you want, I apologize.

How to correctly use a callback function in NodeJS

Alright. Trying to make a very simple request here. First code with asynchronous Nodejs. According to everywhere I've checked, I'm doing this right. None of them explained really how callbacks work, they just say what to do, so I have no way of figuring it out intuitively.
const request = require("request");
function fetchData(url, json, callback) {
request({
url: url,
json: json,
method: "get"
}, callback(error, response, body))
}
console.log(fetchData("https://www.yahoo.com", false, function(error, response, body) {
if(!error && response.statusCode == 200) {
return body;
} else {
return error;
}
}));
Thanks
Two things- first, pass the callback variable into request(), don't call the function.
callback vs callback()
Second, you can't use the return value from the callback function. Call console.log() from inside the callback function.
Code with changes:
const request = require("request");
function fetchData(url, json, callback) {
request({
url: url,
json: json,
method: "get"
}, callback)
}
fetchData("http://www.yahoo.com", false, function(error, response, body) {
if(!error && response.statusCode == 200) {
console.log(body);
} else {
console.log(error);
}
}));

How to use Nodejs "request" work aysn in AWS Lambda?

When I'm trying to use "request" to access external API and get back the response in AWS Lambda, I don't know how to properly put my "return" code to return the response.
NodeJs 8.10
var request = require('request');
module.exports.sendcode = async (event) => {
let options = {
url: 'https://api.netease.im/sms/sendcode.action?' + content,
method: 'POST'
};
return await request(options, function (error, response, body) {
console.log(body);
return {
statusCode: 200,
body: JSON.stringify({
message: body,
input: event,
}),
};
});
};
When I run this code in serverless framework, I got a null response, there is nothing in the body, actually it should have at least the "input" attribute.
But console.log already logs the actual response from API.
It looks like my "return" code is not executed at all.
(If I remove async and await, then the program hangs until timeout)
Can anyone help how to modify this code to make it work?
Request does not use promises, so your await keyword is doing nothing. If you want to use promises with request, you need to find a library that supports promises, as noted here: https://www.npmjs.com/package/request#promises--asyncawait A popular option is https://github.com/request/request-promise-native
However, it is a simple matter to simply wrap a request in a promise, so that you don't need to use another dependency
var request = require('request');
const requestHandler = (options) => new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) {
console.error(error);
reject(error);
} else {
console.log(response, body);
resolve({ response, body });
}
});
});
module.exports.sendcode = async (event) => {
let options = {
url: 'https://api.netease.im/sms/sendcode.action?' + content,
method: 'POST'
};
const { response, body } = await requestHandler(options);
return {
statusCode: 200,
body: JSON.stringify({
message: body,
input: event,
})
}
};
Instead of writing your own promise wrapper, maybe request-promise pacakge with promise wrapper on top of request by the same authors, would be of interest to you.
const rp = require('request-promise')
module.exports.sendcode = async (event) => {
let options = {
url: 'https://api.netease.im/sms/sendcode.action?' + content,
method: 'POST'
};
const body = await rp(options)
console.log(body);
return {
statusCode: 200,
body: JSON.stringify({
message: body,
input: event,
}),
};
};
If you want full response you've to simply set resolveWithFullResponse to true
let options = {
url: 'https://api.netease.im/sms/sendcode.action?' + content,
method: 'POST',
resolveWithFullResponse: true
};
// now response contains full respose
const response = await rp(options)
// response.body
// response.statusCode
Use Async/Await with promises. You cannot use Async-Await syntax with callback. Either you must write a promise wrapper for your 'request'callback or you can use request-promise module which is already available.
I have already provided answer for similar problem which you can refer here.
Undefined value after returning an array of values from a MySQL query in a different file

how to make async/await work properly in node js?

i am new to node js coding i have two functions in my code one of them,i have made async using async keyword but the issue is it doesn't work the output from second function comes before the first function but i want the output of first function before the second function below given is my code
var request = require("request").defaults({jar: true});
var cookieJar = request.jar();
var options = { method: 'POST',
url: 'http://69.30.210.130:8082/api/session',
headers:
{ 'content-type': 'application/x-www-form-urlencoded' },
form: { email: 'admin', password: 'admin' } };
request(options, async function (error, response, body) {
if (error) throw new Error(error);
let bod=await body;
console.log(bod)
});
var options = { method: 'GET',
url: 'http://69.30.210.130:8082/api/devices',
qs: { id: '1' },
headers:
{ 'postman-token': '021a3566-e1ea-4dd4-4ceb-c81ecd25ddd1',
'cache-control': 'no-cache' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
request uses callbacks as default, it means when you want to chain multiple request, you have to do in this manner:
// first request
request({...}, function(error, response, body1) {
if (error) return console.error('Error', error.message);
// second request
request({...}, function(error, response, body2) {
if (error) return console.error('Error', error.message);
console.log(body1, body2);
});
});
async/await is meant to simplify working with promises, so you can use request-promise:
const rp = require('request-promise');
(async function() { // await can be called only from within an async func
try {
const body1 = await rp({...}); // first request
const body2 = await rp({...}); // second request
console.log(body1, body2);
} catch (e) {
console.error('Error', e.message);
}
})();
Here, the body2 will be resolved after body1 has been resolved. This means async/await brings a synchronous behavior into the asynchronous processing.
You can use axios which is Promises-base out of the box.
EDIT: async from callbacks removed, axios reference added

I am learning about callback functions and API

Here I am learning about Callback functions and API to make weather app on node but when I am running the app on Terminal it says undefined I don't know why?
const request = require("request");
request({
URL: "http://maps.googleapis.com/maps/api/geocode/json?address=1301%20lombard%20street%20philadelphia",
json: true
}, (error, response, body) => {
console.log(body);
});
You are calling request incorrectly. You need to call it like so:
request("http://maps.googleapis.com/maps/api/geocode/json?address=1301%20lombard%20street%20philadelphia", {
json: true
}, (error, response, body) => {
console.log(body);
});
alternatively
request({
url: "http://maps.googleapis.com/maps/api/geocode/json?address=1301%20lombard%20street%20philadelphia",
json: true
}, (error, response, body) => {
console.log(body);
});
Notice the url property in lowercase, whereas yours was uppercase
Refer to https://github.com/request/request#requestoptions-callback

Resources