Unable to access response object data outside the function in node js - node.js

I am using node js and making a call to spotify API and receive the response in body object, as shown in below code:
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
request.get(options, function(error, res, body) {
console.log(body)
});
This gives me output:
But now when I try to access the body object outside the function I get undefined. I think the problem is that I am making an asynchronous call and so before the response is received the statements where I make use of body variable outside function are executed. But I am a bit confused about how to get to the solution.
Any help is appreciated
Edit:
request.get(options, function(error, res, body) {
console.log(body)
response.render('user_account.html', {
data: body
})
});
And it gives the output:

Use promise.
You can try following:
const apiCall = () => {
return new Promise((resolve, reject) => {
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
request.get(options, function(error, res, body) {
if(error) reject(error);
console.log(body);
resolve(body);
});
});
}
apiCall().then((body) => {
// do your things here
})
.catch((err) => console.log(err));

Related

trouble with parsing in JSON

i am trying to run this code but it keeps giving me a ReferenceError: json is not defined. Am I putting the JSON parse in the wrong position or something? This is basically a scraper, so it returns a lot of information and that is why it needs to be parsed
const request = require('request');
const options = {
method: 'GET',
url: 'https://siteToParse.com/api/v1/timelines/public',
json: true,
};
obj = JSON.parse(json);
request(options, function(err, res, body) {
if (err) {
console.dir(err);
return;
}
console.log('headers', res.headers);
console.log('status code', res.statusCode);
console.log(body);
});
EDIT: I changed it to obj = JSON.parse(JSON.stringify(body)) and it didn't throw any errors at all. But it's still returned a lot of information, and I'm not sure what to do with it?
I think you should rewrite it as this:
const request = require('request');
const options = {
method: 'GET',
url: 'https://siteToParse.com/api/v1/timelines/public',
json: true,
};
request(options, function(err, res, body) {
if (err) {
console.dir(err);
return;
}
console.log('headers', res.headers);
console.log('status code', res.statusCode);
console.log(body);
obj = JSON.parse(body); //---------------------> call to parse should come here
console.log(obj);
});

how to get data outside request

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.

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

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);
}
};

How to pass the information from function in the Express get API in MEAN Stack

Here I have a function hsResponse which is as below and in the console.log I am getting the proper body response when I run this standalone, but now I wanted call inside the app.get() method and I wanted to put the response of hsResponse to the app.get() API response.
After running the API I wanted to get the body (the value which is printed in the console.log) of hsResponse instead of Root API.
How can I achieve this?
var hsResponse = request({
proxy: proxyUrl,
url: request_data.url,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}, function (error, response, body) {
console.log(body);
});
app.get('', (req, res) => {
res.send('Root API');
});
Why not use a function with a callback passed in parameter to handle the request result:
var hsResponse = function (done) {
// done is a function, it will be called when the request finished
request({
proxy: proxyUrl,
url: request_data.url,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}, function (error, response, body) {
if (error) return done(error);
done(null, body);
});
}
app.get('', (req, res) => {
hsResponse( function (err, body) {
if (err) throw err;
// get body here
res.send('Root API');
} );
});
Edit the code above buffers up the entire api response into memory (body) for every request before writing the result back to clients, and it could start eating a lot of memory if there were many requests at the same time. Streams, by using streams we could read one chunk at a time from the api response, store it into memory and send it back to the client:
app.get('', (req, res) => {
request({
proxy: proxyUrl,
url: request_data.url,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}).pipe(res);
});
Reference: stream handbook
You can just put the code inside:
app.get('', (req, res) => {
var hsResponse = request({
proxy: proxyUrl,
url: request_data.url,
headers: request_data.headers,
method: request_data.method,
form: oauth.authorize(request_data)
}, function (error, response, body) {
res.send(body); //<-- send hsResponse response body back to your API consumer
});
});

Resources