This question already has answers here:
NodeJS get async return value (callback) [duplicate]
(2 answers)
Closed 5 years ago.
I'm working on a module that returns a the data retrieved from an http request using the request module. However, I'm having a problem when I want to pass the data out of the function. Take this, for example.
function getData(term) {
var parsedData
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
parsedData = doSomethingTo(body);
}
});
return parsedData;
}
This method doesn't work, since the function getData() performs asynchronously and the value is returned before the request can actually return the proper data.
function getData(term) {
var parsedData
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
parsedData = doSomethingTo(body);
return parsedData;
}
});
}
This method doesn't work either, as it will merely make the request function return the parsed data, and not the getData function.
How could I make the parent function return the data parsed from the request function?
use Promise like this :
function getData(term) {
return new Promise(function(resolve){
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
var parsedData = doSomethingTo(body);
resolve(parsedData);
}
});
});
}
and you can call your function like this :
getData(term).then(function(data){
//console.log(data);
})
use the bluebird promise module very fast.
var Promise = require('bluebird');
function getData(term) {
return new Promise(function(resolve,reject){
if (!err && response.statusCode == 200) {
var parsedData = doSomethingTo(body);
resolve(parsedData);
}else{
reject(err);
}
});
};
then the place you are calling the function do this;
var promise = getData(term);
promise.then(function(data){console.log(data)}).catch(function(err){console.error(err)});
Related
I have created one NODE JS URL request to get JSON and pass it to the new variable var1.
Var1 can get data within request function when call var1 outside of request it returns null value why? how to get data from URL request and pass it to a new variable outside the Request URL?
function datadata() {
var var1 = 0;
var request = require('request');
request('http://x.x.x.x/json', function (error, response, body) {
if (!error && response.statusCode == 200) {
var importedJSON = JSON.parse(body);
var1 = importedJSON.result.data;
// show value of var1
console.log(var1);
}
});
// cannot show value of var1
console.log(var1);
return var1;
}
function datadata(){
var var1 = 0;
var request = require('request');
return new Promise(function(resolve, reject){
request('http://x.x.x.x/json', function (error, response, body) {
if (err) return reject(err);
try {
if (!error && response.statusCode == 200) {
var importedJSON = JSON.parse(body);
var1 = importedJSON.result.data;
console.log(var1);
} catch(e) {
reject(e);
}
});
});
}
datadata().then(function(res) {
console.log(res);
}).catch(function(err) {
console.err(err);
});
you can't get something outside the request that easy anyway you can try to use Promise
Example
const request = require('request');
var p = new Promise((resolve, reject) => {
request('http://x.x.x.x/json', function (error, response, body) {
if (!error && response.statusCode == 200) {
var importedJSON = JSON.parse(body);
resolve(importedJSON.result.data)
}
});
p.then((data) => {
console.log(data);
})
You can use a callback to the datadata like so
Check whether the body is found on the response, in that case change your code to
request('http://x.x.x.x/json', function (error,response) {
and
var importedJSON = JSON.parse(response.body);
You should do this because your importedJSON may not be having data because according to your code it's data comes from (body)
Mostly likely the json data will be found on the response.body.
Then we callback the specific data you want, in your case it's result.data. Again make sure the result.data can be found on the raw json data that the request gives you otherwise it won't output anything because there's nothing to output, most likely you will get errors
function datadata() {
var var1 = 0;
var request = require('request');
request('http://x.x.x.x/json', function (error,body,response) {
if (error && response.statusCode == 200) {
callback("There was an error")
}else{
var importedJSON = JSON.parse(body);
callback(importedJSON.result.data);
// show value of var1
console.log(var1);
});
}
datadata((error, var1) => {
if(error){
return console.log(error)
}
console.log(var1
})
I am calling network requests in a forEach loop, each request returns a new object which I would like to push to an array that is outside the forEach. When it is called after awaiting for the network requests to complete, it returns as empty "[]".
return this.get(urlOne, function (error, response) {
if (response.statusCode === 200) {
let array = [];
stores.forEach((store) => {
this.get(urlTwo, function (error, response) {
if (response.statusCode === 200) {
array.push(response.body);
}
});
});
console.log(array);
}
});
This is just a guess but, stores.forEach contents are async thus console.log(array) is called right after stores.forEach() is calle d(not completed) meaning array is blank.
console.log(array); probably needs to be called when the requests are actually done not right after they are made.
Simplest way to test if this is true is to see the array for every push if you see the array growing with your data there is the problem.
return this.get(urlOne, function (error, response) {
if (response.statusCode === 200) {
let array = [];
stores.forEach((store) => {
this.get(urlTwo, function (error, response) {
if (response.statusCode === 200) {
array.push(response.body);
console.log(array);
}
});
});
}
});
(EDIT)
if (response.statusCode === 200)
array.push(response.body);
else if(response.statusCode === 204)
console.log(array);
Status code 204 means No Content, if this isn't being sent automatically or an equivalent, you may need to send it manual some how.
I was called function inside setinterval. But i don't take return value from function.
My code:
function getApiData() {
request({
url : 'http://testest.com',
json : true
}, (error, response , body) => {
if(!error && response.statusCode == 200){
return JSON.stringify(body);
}
else{
return undefined;
}
});
}
Call:
setInterval(() => {
var data = getApiData();
console.log(data);
}, 2000);
Output : Undefined
Please help me. (I am learning new)
As #Aravindan Ve pointed out, there is no way to get retrieve the value returned by that function.So, define a different function
functionPrintResponse(res){
console.log(res)
}
and instead of returning there, invoke functionPrintResponse(JSON.stringify(body))
I'd like to read some information from an remote CSV file using a callback function. Not sure, how exactly to do this.
function:
function getRoomsFromCSV(allRoomsArray) {
var request = require('request');
request('http://localhost:3333/rooms.csv', function (error, response, body) {
if (!error && response.statusCode == 200) {
...
allRoomsText = allRoomsText.substr(0,allRoomsText.length-1) + ']}';
var allRoomsArray = JSON.parse(allRoomsText);
}
})
}
I'd like to call the function and loop through the result array.
var rooms = [];
getRoomsFromCSV( function (rooms) {
for(var i = 0; i < rooms.length; i++) {
console.log("i:",i);
}
However, the for loop is never called and the result (room) seems to be empty.
Try like this
function getRoomsFromCSV(allRoomsArray) {
var request = require('request');
request('http://localhost:3333/rooms.csv', function (error, response, body) {
if (!error && response.statusCode == 200) {
...
allRoomsText = allRoomsText.substr(0,allRoomsText.length-1) + ']}';
allRoomsArray(JSON.parse(allRoomsText)); //response params to callback
}
})
}
You sent callback to retrieve response. so call that callback inside the async function
I'm trying to send JSON from two urls to one webpage(one that I am creating). It works perfectly when I send one request, but as soon as I add another request it sends an error saying "Can't set headers after they are sent:.
app.get("/service", function(req, res) {
request("http://example.com", function(error, response, body) {
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
res.render("example.ejs", { data: data });
}
})
request("http://123.com", function(error, response, body) {
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
res.render("example.ejs", { data: data });
}
})
});
This error happens because you render example.ejs twice this not allowed. I will show you two ways to achieve your goal without any error.
1) This way is a best practice.
// Install request-promise package first using this command below:
npm install request-promise;
// then replace your code with this one below:
app.get("/service", function(req, res) {
var request = require('request-promise');
var data1;
request("http://example.com")
.then(function(data) {
data1 = JSON.parse(data);
return request("http://123.com");
})
.then(function(data) {
data2 = JSON.parse(data);
console.log('data1', data1, 'data2', data2);
res.render("example.ejs", { data1: data1, data2: data2 });
});
});
and second way:
2) This way is bad practice avoid to use callback inside callback, but anyway it works.
app.get("/service", function(req, res) {
request("http://example.com", function(error, response, body) {
if (!error && response.statusCode == 200) {
var data1 = JSON.parse(body);
request("http://123.com", function(error, response, body) {
if (!error && response.statusCode == 200) {
var data2 = JSON.parse(body);
console.log('data1', data1, 'data2', data2);
res.render("example.ejs", { data1: data1, data2: data2 });
}
});
}
});
});
Summary: I suggest you to use 1 way, read this article about promises:
https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/ and write clean code. I simply explain that promises are tool to avoid callback inside callback.