ExpressJS to ejs, getting HTTP 500 error - javascript

I have the following code, but I'm getting HTTP 500 error and the page is being re-directed to error.ejs.
However, the console.log(body) works fine. The problem is being seen in res.render. I'm unable to see any error in console (Tried by setting the env=development too)
var express = require('express');
var router = express.Router();
var request = require('request');
/* GET home page. */
router.get('/', function(req, res, next) {
// Set the headers
var headers = {
'Subscription-Key': 'XXXXXXXX',
'Content-Type': 'application/x-www-form-urlencoded'
}
// Configure the request
var options = {
url: 'http://External_Web_Service_REST_URL',
method: 'GET',
headers: headers
}
var result;
// Start the request
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
result = body;
console.log(result); //This works
}
})
res.render('in', {
title: JSON.parse(result)
}); //Problem seen here, No logs printed
});
module.exports = router;

The problem here is that res.render is executed before request call completes.
Remember request is async. The fix is to move res.render inside request callback
....
router.get('/', function(req, res, next) {
...
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
result = body;
console.log(result); //This works
//respond from here
res.render('in', {
.parse(result)
});
} else {
res.render('error');
}
})
})
module.exports = router;

Related

response.status code is Undefined while using an API

While using an API I am getting undefined rather then the status code like 200 or 404.
app.get('/', function(req, res){
const url = ''; //The API key
https.get(url, function(response){
console.log(response.statuscode);
});
res.send('App is running');
});
it should be : response.statusCode
const req = https.request(options, (response) => {
console.log('statusCode:', response.statusCode);
});

How to add Get or POST request in the following code

How to add Get or POST request in the following code. My code is running fine. However, how can i add request like GET, POST, PUT OR DELETE
var expect = require('chai').expect;
var request = require('request');
describe('Status and content', function() {
describe ('Main page', function() {
it('status', function(done){
request('http://localhost:3000/', function(error, response, body) {
expect(response.statusCode).to.equal(200);
done();
});
});
it('content', function(done) {
request('http://localhost:3000/' , function(error, response, body) {
//expect(body).to.equal('Hello World');
done();
});
});
});
describe ('About page', function() {
it('status', function(done){
request('http://localhost:3000/', function(error, response, body) {
expect(response.statusCode).to.equal(200);
done();
});
});
});
});
Also, before running this code how i can install and run the JSON server so the api is ready on the localhost. So i do not have to manually do it.
https://medium.com/codingthesmartway-com-blog/create-a-rest-api-with-json-server-36da8680136d?fbclid=IwAR2mEtB6-BKAsSgUto3aOTjx8WmAbsfKB6RkSvHeZbI4Jt0fiqMwbV_QvGw
You can use request module in this way.
let options = {};
options.method = 'GET';
options.uri = 'http://localhost:3000/';
request(options, function(err, res, body){
//....
});
Also for 'POST',
let options = {};
options.method = 'POST';
options.uri = 'http://localhost:3000/';
options.body = {payload};
options.headers = {}; //headers if any
request(options, function(err, res, body) {
//.....
});

Node.js & Express.js/Jade res.render returns res.render is not a function

I haven't been able to find an answer to this error as of yet and am wondering if it has to do with version 4 of Express
controller.js
var request = require('request');
var apiOptions = {
server : "http://localhost:3000"
};
if(process.env.NODE_ENV === 'production') {
apiOptions.server = "https://heroku_path";
}
module.exports.homelist = function(req, res) {
var requestOptions, path;
path = '/api/locations';
requestOptions = {
url: apiOptions.server + path,
method: "GET",
json: {},
qs : {
lng : -117.929835,
lat : 33.614675,
max : 30000
}
};
request(requestOptions, function(err, res, body) {
renderHomepage(req, res, body);
});
var renderHomepage = function(req, res, body) {
res.render('jade-template', {
title: 'I'm a main title',
pageHeader: {
title: 'I'm a title',
strapline: 'I'm a strapline'
},
locations: body,
sidebar: 'yadda yadda'
});
};
The homelist function gets called from my routes.js which is then where my API gets called from my request with the query found in requestOptions.
however when the request callback is fired and renderHomepage in invoked with the API variable body I get the error:
res.render('jade-template', {
^
TypeError: res.render is not a function
All my routes are set up and tested fine. Does anyone have a solution for this?
The res argument in the renderHomepage function (the request's callback) is not the same as the res of the express route!
Change your call the request to something like:
request(requestOptions, function(err, serverRes, body) {
renderHomepage(req, res, body);
});
Then the response to your request to /api/locations is serverRes, and the response you send to your client is res.

Exporting module in node.js

I have the following my custom module that successfully exports.
module.exports = function(callback) {
var request = require("request")
var url = "http://sheetsu.com/apis/94dc0db4"
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
callback(body)
}
})
Now if I try to change the way to export this as the following, I get 404 error.
var data = function(callback) {
var request = require("request")
var url = "http://sheetsu.com/apis/94dc0db4"
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
callback(body)
}
})
}
module.exports = data;
What am I doing wrong?
UPDATE
This is the route index.js that renders the received data.
var data = require('../lib/data.js');
data(function(data) {
router.get('/', function(req, res, next) {
res.render('index', {
title: 'Express',
data: data
});
});
});
And the error is at at /Users/xxxxx/Dev/Project/app.js:32:13
I haven't changed any other codes except how I changed the export part.
You should call your function inside the route, not vice a verca:
router.get('/', function(req, res, next) {
data(function(d) {
res.render('index', {
title: 'Express',
data: data
});
});
});

node.js/express chaining multiple get commands

I have a route I that in order to get all the data needs to access the API server multiple times (according to the data that was given).
Now I need to add a third access to the server and it's getting rather unreadable.
The following code is working, but I have a feeling I'm not doing it right (promises?) - couldn't figure out what exactly is recommended in this case
The code: (stripped down to emphasise the point)
router.get('/', function(req, main_response) {
http.get(FIRST_API_COMMAND, function (res) {
var moment_respose_content = '';
res.on("data", function (chunk) {
moment_respose_content += chunk;
});
res.on('end',function(){
if (res.statusCode < 200 || res.statusCode > 299) {
main_response.send('error in getting moment');
return;
}
var response = JSON.parse(moment_respose_content );
if (response.success)
{
var data = response.data;
//doing something with the data
http.get(SECOND_API_COMMAND, function (res) {
res.on("data", function (chunk) {
comment_respose_content += chunk;
});
res.on('end',function(){
var response = JSON.parse(comment_respose_content);
if (response.success)
{
var comments = response.data;
main_response.render('the page', {data: data});
return;
}
});
}).on('error', function (e) {
console.log("Got error: " + e.message);
main_response.send('Error in getting comments');
});
return;
}
});
}).on('error', function (e) {
console.log("Got error: " + e.message);
main_response.send('Error in getting moment');
});
});
You can write a middleware for each remote action, and then use those middlewares before the get handler, so the get handler can simply access their results. (Promises can help if you need to start subsequent requests before waiting for earlier ones to finish, but that situation is rare.)
For example, using express middleware to fetch each remote data independently:
var request = require('request');
var express = require('express');
var app = express();
var router = express.Router();
/* middleware to fetch moment. will only run for requests that `router` handles. */
router.use(function(req, res, next){
var api_url = 'https://google.com/';
request.get(api_url, function(err, response, body) {
if (err) {
return next(err);
}
req.moment_response = response.headers["date"];
next();
});
});
/* middleware to fetch comment after moment has been fetched */
router.use(function(req, res, next){
var api_url = 'https://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new';
request.get(api_url, function(err, response, body){
if (err) {
return next(err);
}
req.comment_response = parseInt(body);
next();
});
});
/* main get handler: expects data to already be loaded */
router.get('/', function(req, res){
res.json({
moment: req.moment_response,
comment: req.comment_response
});
});
/* error handler: will run if any middleware called next() with an argument */
router.use(function(error, req, res, next){
res.status(500);
res.send("Error: " + error.toString());
});
app.use('/endpoint', router);
app.listen(8000);
Often the remote data you want to fetch is based on some parameter of the main request. In this case you would want to use req.param() instead of App.use() to define the data-loading middleware.

Categories