Is there a way to use node module "request" multiple times in one route and have the results display on the same rendered ejs template page?
Goal: I want to display eBook information from the iTunes Store using their Search API. Right now I can get an ebook's price in one territory, but I would like to display prices for the same ebook in multiple countries. To get each different price, I need to use a different URL, either a default ending, "&country=gb", "&country=fr" etc. I can get prices for each of the 5 countries I am interested in, but I can't get them all on the same page. How can I construct my route and prepare my variables so that I can display information from all of these countries when I render one page?
I am using node, express and ejs, and I am making the http request using the "request" node module. Here are the basics of the form I'm using, where I enter the ISBN in the searchTerm field. (there's more, but it's bulky.)
<form action="/search">
<select name="searchTerm">
Code that is working now for getting info on the book in one territory:
app.get('/search', function(req, res){
var searchRequest = req.query.searchTerm;
var searchURL = "http://itunes.apple.com/lookup?isbn=" + searchRequest;
request(searchURL, function(error, response, body){
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
console.log(data.results[0]);
var iTunesResults = data.results[0];
res.render("test", {
iTunesResults: iTunesResults,
searchRequest: searchRequest
});
}
});
});
If I make a few changes in this code I can get information on the same ebook in a different country with just a few changes. Below is the code for great britain, and it works on its own, I just want to get results from both of these searches displaying at once, and I'm not sure where to begin.
app.get('/search', function(req, res){
var searchRequest = req.query.searchTerm;
var gbSearchURL = "http://itunes.apple.com/lookup?isbn=" + searchRequest + "&country=gb";
request(gbSearchURL, function(error, response, body){
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
console.log(data.results[0]);
var iTunesResults = data.results[0];
res.render("test", {
iTunesResults: iTunesResults,
searchRequest: searchRequest
});
}
});
});
What I want to do is make an additional request to Apple, using the same search term here but adding a country identifier to the end of the searchURL I'm passing into request. However, if I try to call request again and pass all of the results variables into res.render at once, the result of the first request will not be available inside the second request.("ReferenceError: iTunesResults is not defined")
I'm guessing there is a way to have an array of searchURL's and an array of results (req.query.searchTerm), then I can pass the array or a more complicated object in when I render the test.ejs template. Am limited to one http request per app.get route? (Forgive me if that should be obvious, but I just want to grab this pricing information and display it next to each other. Also, I figured it would be better to be verbose in my question.)
Ok! I got it resolved using the "async" node library. http://www.github.com/caolan/async
With that I can call multiple functions in parallel, and when they're done I can just pass back the results to a template to render.
app.get('/search', function(req, res){
async.parallel([
function(done){
var searchRequest = req.query.searchTerm;
var gbSearchURL = "http://itunes.apple.com/lookup?isbn=" + searchRequest + "&country=us";
request(gbSearchURL, function(error, response, body){
if (!error && response.statusCode == 200) {
// console.log(body)
var data = JSON.parse(body);
// below shows whole object of result 0
console.log(data.results[0]);
done(null, data.results[0]);
}
});
},
// UK pricing
function(done){
var searchRequest = req.query.searchTerm;
var gbSearchURL = "http://itunes.apple.com/lookup?isbn=" + searchRequest + "&country=gb";
request(gbSearchURL, function(error, response, body){
if (!error && response.statusCode == 200) {
// console.log(body)
var data = JSON.parse(body);
// below shows whole object of result 0
console.log(data.results[0]);
done(null, data.results[0]);
}
});
},function(err, iTunesResults){
res.render("test", {
iTunesResults: iTunesResults,
searchRequest: req.query.searchTerm
});
})
});