Multiple Get Requests Within One Function - node.js

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.

Related

Node Js get data from URL and pass to new variable

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

How to call rest api in express js

I am new in nodejs and I am using express js, I am calling REST API and want to show the response, but my problem is that the response is showing in console.log but I want to pass the body(response) in assistant.ask, where I am wrong here is my code:
var request = require('request');
let rawInput = function (assistant) {
let rawInput = assistant.getRawInput();
request.post(
'http://xxxxxxx.ngrok.io/api/v1/240/respond',
{ json: { query: rawInput } },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
assistant.ask(body);
}
else{
console.log(error);
}
}
);

Why I cannot get the data from body in request method

I try to get the JSON data from a GET request and I can see the information from body in request. How can I get the data?
Currently use NodeJs, basic in JavaScript.
var definedURL="https://api.etherscan.io/api?module=account&action=tokentx&contractaddress=0x6a750d255416483bec1a31ca7050c6dac4263b57&page=1&offset=100&sort=asc&apikey=YourApiKeyToken";
var request = require('request')
var information=[];
request({
url: definedURL,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
//console.log(body.result[0]);
information.push(body.result[0]);
}
});
console.log(information);
I expect after this I will see the contain of result coming out, but now it still shows [].
Because you are making asynchronous request. Asynchronous action will get completed after the main thread execution.
console.log(information) // execute before your call
You need to wait for the request call to get completed and received data get pushed to information
There can be two ways to do this -
Async/Await- MDN Reference
var definedURL="https://api.etherscan.io/api?module=account&action=tokentx&contractaddress=0x6a750d255416483bec1a31ca7050c6dac4263b57&page=1&offset=100&sort=asc&apikey=YourApiKeyToken";
var request = require('request')
var information=[];
async () => {
await request({
url: definedURL,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
//console.log(body.result[0]);
information.push(body.result[0]);
}
});
console.log(information)
}();
Promise MDN reference
var definedURL="https://api.etherscan.io/api?module=account&action=tokentx&contractaddress=0x6a750d255416483bec1a31ca7050c6dac4263b57&page=1&offset=100&sort=asc&apikey=YourApiKeyToken";
var request = require('request')
var information=[];
var Promise = new Promise((resolve,reject) => {
request({
url: definedURL,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
//console.log(body.result[0]);
information.push(body.result[0]);
resolve()
}
});
})
Promise.then(() => {
console.log(information)
})

Async Parallel & Request Package returning API results out of order (NodeJS/Express)

I currently have an asynchronous API call that makes at this moment 19 different request to a string end-point using the async & request NPM packages. I just discovered that towards the end of my requests, the actual object that is being returned is the data for the request prior. Here is an example of my code:
router.get('/', function(req, res) {
async.parallel([
function(next) {
request(queryString + 'end point link', function(error, response, body) {
if (!error && response.statusCode == 200) {
var variable0 = JSON.parse(body);
return next(null, variable0);
};
console.log(error);
next(error);
});
},
function(next) {
request(queryString + 'end point link', function(error, response, body) {
if (!error && response.statusCode == 200) {
var variable19 = JSON.parse(body);
return next(null, variable19);
};
console.log(error);
next(error);
});
}],
function(err, results) {
res.render("view", {
variable0: results[0],
variable1: results[1],
variable2: results[2],
......
......
variable19: results[19]
});
});
});
This was working perfectly until I noticed my last three variables (lets call them 17, 18 and 19) were returning the results of the prior API call. I'm unsure why this is occurring, and any advice would be greatly appreciated.
The results variable async provides is an array, which I've modified into an object at a given index for the appropriate request.
Turns out I missed a faulty request in my code. Issue has been solved. Thanks SO.

Returning a value from a function in node.js

Still learning node. Based upon the following:
https://github.com/request/request
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
I wish to create the above as a reusable block of code so thought I'd wrap it in a function passing the URL as a parameter such as:
var request = require('request');
var URL;
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
function fetchURL (URL) {
request(URL, function (error, response, body) {
if (!error && response.statusCode == 200) {
return body;
}
});
};
var a = fetchURL('http://www.google.com');
console.log(a);
This works however I am unsure of whether "return body" is needed as it also works without this line. Happy to received comments on my coding style too as it's all new to me.
The pattern in Node is to provide a callback as an argument to an asynchronous function. By convention, this callback function has error as its first argument. For example:
function fetchURL(url, callback) {
request(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
callback(null, body);
} else {
callback(error);
}
});
};
fetchURL('http://www.google.com', function(err, body) {
console.log(body);
});
Note that in your snippet, return body; is a return from the anonymous callback function passed into fetchURL(). fetchURL() itself returns nothing.

Resources