how to get data outside request - node.js

I have a scenario where i need to take response (body) of request method outside request. How can i do it?
request.post({
url: 'http://localhost/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
I need this tmsg outside for next processing, Actual scenario is as below.
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
if (mediaCount == 0) {
//var twiml = getResponse(message);
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
}else {
//dosomething which outputs tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});

The problem is you are trying to assign value to a global variable in request.post's callback() which is only called after request.post is executed by Asynchronous logic(API calls are all async), so a better way would be to promisify request.post and await the request.post to make it seem synchronous.
const requestPromisified = requestObject =>
new Promise((resolve, reject) => {
request.post(requestObject, function(err, httpResponse, body) {
if (err) {
reject(err);
}
resolve(body);
});
});
const body = await requestPromisified({
method: "POST",
url: "http://localhost/api/messages",
form: { key: message }
});

You only can do something with tmsg when you made the request so you need to rearrange your code like this:
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
console.log(tmsg);
if (mediaCount === 0) {
//do something with tmsg
} else {
//do something else with tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});
});
Otherwise tmsg will be null because there was no request made to fill that variable.

Related

How can I send the response.body out of request module function?

I started by creating a return statement in the request function (I have linked a picture) and then console.log it outside of the function but that didn't work out.
My server code
var options = {
'method': 'POST',
'url': 'http://localhost:8080/ES_Part1/api/user/getUser',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
'username': username,
'password': password
}
};
requestToApi(options, function(error, response) {
if (error) throw new Error(error);
console.log("Send form data to remote api and to return the user from Spring")
console.log(response.body);
return response.body
});
var fromapi = response.body;
res.end();
Example:
I suggest you use a Promise-based approach here rather than the callback-style that you're using for requestToApi. If you're using the request package, there is a Promise-based version available.
Alternative solution would be to create a promise yourself, like such:
var requestToApiAsPromise = (options) => {
return new Promise((resolve, reject) => {
requestToApi(options, (error, response) => {
if (error) {
reject(error)
return
}
resolve(response.body)
})
})
}
Then you can use this method in your middleware:
app.post("/checkUser", (req, res) => {
async function process() {
try {
var username = req.body.username
var password = req.body.password
var options = {...}
var response = await requestToApiAsPromise(options)
// response => response.body
// do whatever
res.end()
} catch (error) {
next(error)
}
}
process()
})
This method uses async/await so that it lets you write your code as if you were doing things synchronously, so it's making it easier to make asynchronous calls and have them "wait" before the next line gets executed.
👨‍🏫 If you want to get respose.body outside the handler, than you can use this code below 👇:
// an example get function
app.get('/users', async(req, res) => {
var options = {
'method': 'POST',
'url': 'http://localhost:8080/ES_Part1/api/user/getUser',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
'username': username,
'password': password
}
};
const result = new Promise((resolve, reject) => {
requestToApi(options, function(error, response) {
if (error) return reject(error);
return resolve(JSON.parse(response.body));
});
})
// make sure, to use async in your function
// because we're using await here
var fromapi = await result;
// It's working here
console.log(fromapi);
res.end();
})
That code above 👆, only an example that you can use to read response.body. If you want to handle the error from that code above, you can use like this code below:
try {
// make sure, to use async in your function
// because we're using await here
var fromapi = await result;
// It's working here
console.log(fromapi);
} catch(ex) {
// print error response
console.log(ex.message);
}
I hope it's can help you 🙏.

How to return a string from a node js api call

I have using a code snippet which will return a value after post rest call to an api.
But where ever i am calling the function its not returning the value and prints undefined.
when ever i will call any where getAccessToken(), its says undefiuned, but ifi print the value am getting the output.
How do the called will get the return value, do i need to change anything in the below code.
Thanks
var getAccessToken = exports.getAccessToken = function (res) {
// body...
const request = require('request');
const authKey='EAcEa4o4SkBLo9IpZpW4Y7oDn7d6b30GlouNh28pJ6Q='
const ContentType='application/x-www-form-urlencoded' ;
var postData={
'grant_type':'client_credentials'
};
const options = {
url: 'https://xyz/v1/login',
method: 'POST',
headers: {
'Content-Type': ContentType,
'Authorization':authKey
},
body:require('querystring').stringify(postData)
};
var token;
request(options, function(errror, response, body) {
//console.log(JSON.parse(body));
token= JSON.parse(body).access_token;
});
return token;
}
Your function doesn't return anything. You may use async/await, promises or callbacks to fix it.
exports.getAccessToken = async (res) => {
...
return await request(...)
}
OR
exports.getAccessToken = function(res) {
...
return new Promise(function(resolve, reject) {
...
request(options, function(errror, response, body) {
var token = JSON.parse(body).access_token;
resolve(token);
}
});
}
// Use it like
getAccessToken().then(function(token) { ... });
OR
exports.getAccessToken = function(res, cb) {
...
request(options, function(errror, response, body) {
var token = JSON.parse(body).access_token;
cb(token);
}
}
// Use it like
getAccessToken(res, function(token) { ... });

How can I use the value of the body outside this method?

var request = require('request');
var boardsCall = {
method: 'GET',
url: 'https://api.trello.com/1/organizations/xxxxxxxxxx/boards?filter=open&fields=id,name',
qs: {
key: 'xxxxxxxxxxxxxxxx',
token: 'xxxxxxxxxxxxxxxxxxxxxxxxx'
}
};
function test(url, callback) {
request(url, function(error, response, body) {
if (error) {
return callback(error);
}
callback(null, JSON.parse(body));
})
}
const x = test(boardsCall, function(err, body) {
if (err) {
console.log(err);
}
else {
return body;
}
})
console.log(x);
how can I use the value of the body outside?
to use it in other methods later
I am open to any changes best practices, I read a lot and got a bit confused on the topic of callbacks, promises async await.
In my approach request is wrapped with Promise, test function returns Promise response. Inside the main method test function will be executed synchronously. Once the response value assigned to x do remaining processing logic inside the main() method.
var request = require('request');
var boardsCall = {
method: 'GET',
url: 'https://api.trello.com/1/organizations/xxxxxxxxxx/boards?filter=open&fields=id,name',
qs: {
key: 'xxxxxxxxxxxxxxxx',
token: 'xxxxxxxxxxxxxxxxxxxxxxxxx'
}
};
function test(url) {
//Wrapping request callback with Promise
return new Promise((res, rej)=> {
request(url, function(error, response, body) {
if (error) {
rej(error);
}
res(JSON.parse(body));
})
})
}
async function main() {
try {
const x = await test(boardsCall);
console.log("Result : ", x );
// Remaining logic to process based on x value
} catch(e) {
console.error("Error :", e);
}
}
//Calling main method
main()

Post request to external api

after a post request from an ajax call in angularjs, i want to send the request params from angularjs to an external api. I get all params i want. But I don't know, how i can make a new post request to the api, inside my nodejs url. I need this step to nodejs.
This is my Code
router.post({
url: '/user/:id/sw'
}, (req, res, next) => {
var userId = req.pramas.id;
var firstName = req.pramas.firstName;
var lastName = req.pramas.lastName;
var data = 'test';
res.send(200, data);
});
I found some solutions like this on: (just example code)
request({
uri: 'http://www.giantbomb.com/api/search',
qs: {
api_key: '123456',
query: 'World of Warcraft: Legion'
},
function(error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body);
res.json(body);
} else {
res.json(error);
}
}
});
but this doesn't work. How I can make a new Post Request with the req.params to an external api? Also i need a Response from the api..
Thanks for help and Ideas :)
Its req.params not req.pramas
Try this
var request = require('request');
router.post({
url: '/user/:userId/shopware'
}, (req, res, next) => {
var params = req.params;
request.get({
uri: 'http://www.giantbomb.com/api/search',
qs: params // Send data which is require
}, function (error, response, body) {
console.log(body);
});
});
Try this,
const request = require('request-promise')
const options = {
method: 'POST',
uri: 'http://localhost.com/test-url',
body: {
foo: 'bar'
},
json: true
// JSON stringifies the body automatically
};
​
request(options)
.then(function (response) {
// Handle the response
})
.catch(function (err) {
// Deal with the error
})
var request = require("request");
exports.checkstatus = async (req, res) => { //this is function line you can remove it
try {
var options = {
method: 'POST',
url: 'https://mydoamin/api/order/status',
headers:
{
signature: '3WHwQeBHlzOZiEpK4yN8CD',
'Content-Type': 'application/json'
},
body:
{
NAME: 'Vedant',
ORDERID: 'ORDER_ID1596134490073',
},
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body); //get your response here
});
} catch (error) {
return fail(res, error.message);
}
};

Node.js For Loop async request

I have for loop with a request (and another request in callback).
I have problem with memory usage (when i am go through a lot of request at same time)
here is the sample code :
var request = require('request');
for(var j=1;j<=10;j++){
request({
method: 'GET',
url: 'https://api.domain.com/items/?page='+j+'&limit=1000',
headers: {
'Content-Type': 'application/json'
}}, function (error, response, body) {
var data = JSON.parse(body)
for(var i=0;i<data.length;i++){
request({
method: 'GET',
url: 'https://api.domain.com/itemDetail/'+data[i].id,
headers: {
'Content-Type': 'application/json',
}}, function (error, response, body) {
var itemDetails = JSON.parse(body);
// save items to mongodb
}
}
});
}
The solution suggested to me it was using async module.
After reading documentation i find out eachlimit suit my needs.
The problem i have its i can use eachlimit for second loop but for first loop i dont know how use it (because first loop in not an array).
here code so far i get , and its not working:
var request = require('request');
var mongodb = require('mongodb');
var async = require('async');
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/subtitle';
for(var j=1;j<=10;j++){
request({
method: 'GET',
url: 'https://api-v2.domain.com/news/popular?page='+j+'&limit=1000',
headers: {
'Content-Type': 'application/json',
'api-version': '2',
'api-key': 'my-api-key'
}}, function (error, response, body) {
try {
var data = JSON.parse(body);
} catch (e) {
// An error has occured, handle it, by e.g. logging it
console.log(e);
}
async.each(data, function(item, callback) {
request({
method: 'GET',
url: 'https://api-v2.domain.com/news/'+item.id,
headers: {
'Content-Type': 'application/json',
'api-version': '2',
'api-key': 'my-api-key'
}}, function (error, response, body) {
// sava item in mongodb
})
callback();
}, function(err){
if( err ) {
console.log('A item failed to process');
} else {
console.log('All items have been saved successfully');
}
});
})
}
You can achieve this in a number of ways, one of them would be using whilst. With your code it'd look something like this (removed error handling and request options for readability here):
var requestCount = 0;
async.whilst(
function () {
return requestCount < 10;
},
function (firstCallback) {
request({url: "https://api-v2.domain.com/news/popular?page=" + requestCount + "&limit=1000"}, function (err1, res1, body1) {
var data = JSON.parse(body1);
async.each(
data,
function(item, secondCallback) {
request({url: "https://api-v2.domain.com/news/" + item.id}, function (err2, res2, body2) {
// sava item in mongodb
secondCallback();
});
},
function(err){
requestCount++;
firstCallback();
}
);
});
},
function (err) {
//all requests done
}
);
Once you start to nest so many callbacks, you should probably refactor this and put the second loop in it's own function. For example:
var requestCount = 0;
async.whilst(
function () {
return requestCount < 10;
},
function (callback) {
request({url: "https://api-v2.domain.com/news/popular?page=" + requestCount + "&limit=1000"}, function (err, res, body) {
var items = JSON.parse(data);
getNews(items, function(newsErr){
requestCount++;
callback(newsErr);
});
});
},
function (err) {
//all requests done
}
);
//----------------------------------------------------
function getNews(items, callback){
async.each(items, function(item, itemCallback) {
request({url: "https://api-v2.domain.com/news/" + item.id}, function (err2, res2, body2) {
// sava item in mongodb
itemCallback();
});
}, callback);
}
Also make sure to call the async callbacks within the callbacks of the request (you weren't doing it so in your code).

Resources