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);
});
Related
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) {
//.....
});
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;
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.
I try to learn nodeJS and AngularJS using Clash of clan API available here https://developer.clashofclans.com/#/
My JSON api's return is truncated and i don't know how get the full response.
there is my app.js wrinting with node and express :
var express = require('express')
, https = require('https')
, bodyParser = require('body-parser')
, request = require('request')
, app = express()
, http_port = 3000;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
var options = {
host: 'api.clashofclans.com',
port: 443,
path: '/v1/clans/' + encodeURIComponent("#PP8JC9RQ"),
headers : {
accept : "application/json",
authorization : "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6ImQ4Njg1OGFhLWQzZTUtNDNiOC05MTM1LTBjNzI1ZjI4OGFiMiIsImlhdCI6MTQ1NjMwMTE5MSwic3ViIjoiZGV2ZWxvcGVyLzk1YWM0YjdmLTY5NTQtMDE3MC01ZjAyLTcxNjY1ZDMzYjUwNyIsInNjb3BlcyI6WyJjbGFzaCJdLCJsaW1pdHMiOlt7InRpZXIiOiJkZXZlbG9wZXIvc2lsdmVyIiwidHlwZSI6InRocm90dGxpbmcifSx7ImNpZHJzIjpbIjg3LjIzMS4yMTMuMTU0Il0sInR5cGUiOiJjbGllbnQifV19.SYqeSAF-0_bM1eS2-hnovvj5j-I0SQpdr_kySIiBKw9OkrNuBzZAOAOkiH3fzdKSkcHaJfXzWdXr8JozFfAmJA"
},
method: 'GET'
};
// Route par défaut
app.get("/members", function(req, res) {
console.log("-------------------------------------\n\nroot path !! Let's get clan infos from coc api\n\n-------------------------------------");
var req = https.request(options, function(response){
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
// in console JSON is full but in my html JSON is truncated..
res.send(chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
app.listen(http_port,function(){
console.log("Listening on " + http_port);
});
If someone can teach to a nook :)
Your code is sending the first chunk of the response immediately back to the user. You need to wait until the entire HTTP response is done. Try something like this:
app.get("/members", function(req, res) {
var req = https.request(options, function(response){
var httpResult = '';
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
httpResult += chunk;
});
response.on('end', function() {
res.send(httpResult);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
See how I append to a var each time the data event is called and when it is done - then I send the output.
Because you use send method instead write (send non-streaming). Try this:
app.get("/members", function(req, res) {
https.request(options, function(response){
response.on('data', function (chunk) {
res.write(chunk);
});
response.on('end', function () {
res.end();
});
}).end();
});
response is a stream, you can simply pipe it to res:
app.get("/members", function(req, res) {
https.request(options, function(response) {
response.pipe(res);
});
});
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.