How to render the results of an http request in Express? - node.js

Using Request and Express, how do I access the result of my http request for the purpose of rendering it?
var request = require('request');
var http = require('http');
exports.index = function(req, res){
var apiUrl = 'http://api.bitcoincharts.com/v1/weighted_prices.json';
request(apiUrl, function(err, res, data) {
if (!err && res.statusCode == 200) {
data = JSON.parse(data);
console.log(data);
res.render('index', { data: data });
}
});
};
As it is, the res I'm referring to within the request callback is the raw response object and I'm wondering how to call the response from my exports.index function without the request being inaccessible.

Just rename one of the arguments:
// either this:
exports.index = function(req, response) {
...
response.render(...);
};
// or this:
request(apiUrl, function(err, response, data) {
if (!err && response.statusCode == 200) {
data = JSON.parse(data);
console.log(data);
res.render('index', { data: data });
}
};

Related

Error: Can't set headers after they are sent in loop multiple request

i'm beginner at nodejs, i got a problem when request multiple url in a loop then i render it.
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:491:11)
at ServerResponse.setHeader (_http_outgoing.js:498:)
router.get('/', function(req, res, next) {
setInterval(function(){
request(url1,function (error,response,body) {
var data1 = JSON.parse(body);
request(url2+data1.access_token,function (error,response,body) {
var data_info = JSON.parse(body);
//error when it render
res.render('index', {data_info : data_info});
})
})
},5000);
});
That's not exactly a loop, I understand you mean that you call the same function repeteadly with setInterval().
Once you've sent your first response with res.render(), which finishes the response process for that request, subsequent attempts to use that res object fail.
If you want to send data to the client in 5 seconds interval you should probably either look into websockets or pass the setInterval() calls to the client so it polls your server each 5 seconds, in which case your server code could be changed to:
router.get('/', (req, res) => {
request(url1, (error, response, body) => {
const data1 = JSON.parse(body);
request(`${url2}${data1.access_token}`, (error, response, body) => {
const data_info = JSON.parse(body);
res.render('index', { data_info });
});
});
});
You can make use of Async Module
const async = require('async');
router.get('/', function (req, res, next) {
async.waterfall([
function(callback) {
request(url1, function (error,response,body) {
if(err) {
callback(err)
}else {
var data1 = JSON.parse(body);
callback(data1)
}
})
},
function(data1, callback) {
request(url2+data1.access_token, function(error,response,body) {
if(err) {
callback(err)
}else {
var data_info = JSON.parse(body);
callback(null, data_info)
}
})
}
], function(err, result) {
if(err) {
res.json({success: false, error: err, message: "Something went wrong.!"})
}else {
res.render('index', {
data_info : result
});
}
})
})

how to show error when user search invalid movie data (omdb api with nodejs)

Here is the code for app.js
var express = require('express');
var app = express();
var request = require('request');
var _und = require('underscore');
app.set("view engine", "ejs");
// Search Route
app.get("/", function(req, res) {
res.render("search");
});
// Result Route
app.get("/results", function(req, res) {
var query = req.query.search;
var url = "http://www.omdbapi.com/?apikey=6cf73f27&s=" + query;
// var url = "http://www.omdbapi.com/?apikey=6cf73f27&s=star";
request(url, function(error, response, body) {
if(error && response.statusCode != 200) {
res.render("search", {
warning: "Movie is not in database"
});
} else {
var data = JSON.parse(body);
res.render("results", {
data: data
});
}
});
});
app.listen(9090, function() {
console.log("Movie App has started!!!.....Ctrl+C to Exit.....");
});
Here is the code for my search result page:
<h1>Result:</h1>
<ul>
<% data["Search"].forEach(function(movie) { %>
<li><strong><%= movie["Title"] %></strong> - <%= movie["Year"]%></li>
<% }) %>
</ul>
Search again!
When user search invalid or wrong typo movie
here is the error. I would like to pop up or show error and redirect back to search page.
TypeError: D:\Development App\nodejs(moviedb)\moviedbapp\views\results.ejs:4
You need to check before rendering as api send 200 response code without error, following code may help you
// Result Route
app.get("/results", function(req, res) {
var query = req.query.search;
var url = "http://www.omdbapi.com/?apikey=6cf73f27&s=" + query;
// var url = "http://www.omdbapi.com/?apikey=6cf73f27&s=star";
request(url, function(error, response, body) {
if(error && response.statusCode != 200) {
res.render("search", {
warning: "Movie is not in database"
});
} else {
var data = JSON.parse(body);
if( data.Response == 'False') {
return res.render("search", {
warning: "Movie is not in database"
});
}
res.render("results", {
data: data
});
}
});
});

How to hit third party API form node server.

IndiaSMS is a thirdparty providing sms service I want to hit this api form node server. Any way to request to third party api. Please help..
var express = require('express');
var router = express.Router();
exports.sendOTP = function (userInfo, callback) {
console.log(userInfo);
console.log('Inside SendOTP usin indaSMS');
var indiasmsURL = 'https://app.indiasms.com/sendsms/sendsms.php?username=user&password=pass&type=TEXT&sender=Alerts&mobile=' + userInfo.mobilenumber + '&message=Your%20OTP%20for%203DClubHouse%20is%20' + userInfo.otp + '';
console.log(indiasmsURL);
router.get(indiasmsURL,
function(req, res, next) {
console.log('--------------------------');
console.log(res);
console.log('--------------------------');
})
callback('hello');
};
Thnaks in advance.
This is Mikeal's request library see link here very useful
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
})
Using axios:
axios.get('https://app.indiasms.com/sendsms/sendsms.php', {
params: {
username: user,
password: pass,
type: 'TEXT',
//...
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Or using async/await, you can simply:
let response = await axios.get(indiasmsURL);
if (response.status == 200) {
//console.log(`CC status ${response.status}: `, response.data)
}
You can build your URI like above (stored in indiasmsURL) or specify them in the params of the request if you would prefer.
I would suggest snekfetch or request.

How to make a post request using request module NodeJs express

How to make a proper post request to this endpoint. When I use the POSTMAN I get the correct response but when I call using the below function I get 503 error. The call seems to be fine according to me. I appreciate your help!!
const request = require('request');
const express = require('express');
// Initialize request
var img64Data = "/9j/4AAQSkZJRgABAQAAAQABAAD/2w… "; // Include the entire base64 encoding. // Shown Below in the next page
var send = {"img64": img64Data};
var api_address = "https://8n78hbwks0.execute-api.us-west-2.amazonaws.com/dev/";
// Make Post Request
module.exports = app => {
app.post('/axe', (req, res, next) => {
console.log("inside the axe");
request.post({
url: api_address,
body: JSON.stringify(send),
headers: {"Content-Type":"application/json"}
}, function (error, response, body) {
console.log("hiii");
console.log(response.statusCode);
if (!error && response.statusCode == 200) {
// Successful call
var results = JSON.parse(body);
console.log(results) // View Results
}
});
});
};
You get a 503 Error https://en.wikipedia.org/wiki/List_of_HTTP_status_codes because your server doesn't reply any http code.
if (!error && response.statusCode == 200) {
// Successful call
var results = JSON.parse(body);
console.log(results) // View Results
res.sendStatus(200);
} else {
res.sendStatus(response.statusCode);
}

Unable to return body of request method in nodejs

I'm trying to get a JSON response via the request method and return the output so that i can store it in a variable when the function is called. when i log the response within the request method, it works fine. However when i return the output, it doesn't return.
var getAPIresponse = function(url) {
var request = require('request');
request(url, function(error, response, body) {
if(!error && response.statusCode == 200) {
console.log(body); // WORKS PERFECTLY
return body; // I Believe the issue is here
} else {
console.log("Error: "+ error);
}
});
};
router.get('/', function (req, res) {
var poolList = getAPIresponse("www.addAURL");
console.log(poolList); // DOESN'T WORK. REPORTS AS UNDEFINED
res.render('index', model); // THIS IS JUST SAYS HELLO WORLD
});
What your method actually does is run the following two lines
var request = require('request');
request(url, function(error, response, body) {
...and then fall out of the function right away at which point your calling code gets undefined back. The callback isn't called until the request is done, which may be much later.
To make it work, your function needs a callback too that is called when the function is actually complete, something like;
var getAPIresponse = function(url, cb) {
var request = require('request');
request(url, function(error, response, body) {
if(!error && response.statusCode == 200) {
console.log(body); // WORKS PERFECTLY
} else {
console.log("Error: "+ error);
}
cb(error, body);
});
};
router.get('/', function (req, res) {
var poolList = getAPIresponse("www.addAURL", function(err, poolList) {
// This is run in a callback once the request is done.
console.log(poolList);
res.render('index', model);
});
});
Another way would be to use promises which can clean up the code somewhat when the number of callbacks is getting out of hand.

Resources