I'm using nodejs on nginx server. Sometimes the node app is crashing and returning 'incomplete response received from application'. What is causing this problem?
const Express = require('express');
const BodyParser = require('body-parser');
const Request = require('request');
const Conf = require('./conf');
const {db} = require('./lib/database');
const app = Express();
app.use(BodyParser.json());
app.use(BodyParser.urlencoded({extended: false}));
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'POST');
if ('OPTIONS' == req.method) {
res.header('Access-Control-Allow-Methods', 'POST');
return res.sendStatus(200);
}
next();
});
app.post('/getProperty', (req, res) => {
const sql = "SELECT ('['||(st_asgeojson(geom)::json)||']')::json FROM spt.spt where id=" + req.body.id;
db.query(sql, (err, result) => {
if (err) res.status(err.code).json({code: err.code, message: err.message}).end();
(result.rows.length == 0) ? res.send([]) : res.send(result.rows[0].json);
})
});
app.post('/getAnalysis', (req, res) => {
const sql = "select value from test.test where id=" + req.body.id + " order by value asc";
db.query(sql, (err, result) => {
if (err) result.status(err.code).json({code: err.code, message: err.message}).end();
res.send(result.rows);
})
});
app.listen(3000);
If an error occurs, your code tries sending a response twice. You need to exit the function after sending the error response to the client, so either use return in your if or add an else below for the success response.
Sending multiple responses will dicsonnect the socket in express.
Related
I'm sending post request from "angular->port 4200" to "expressjs server->port 8000".
As an example i'm folowing this example: https://github.com/kuncevic/angular-httpclient-examples/blob/master/client/src/app/app.component.ts
I'm getting two error :
1)undefined from Nodejs(data and req.body.text)
2)Message received from background. Values reset
Angular side:
callServer() {
const culture = this.getLangCookie().split("-")[0];
const headers = new HttpHeaders()
headers.set('Authorization', 'my-auth-token')
headers.set('Content-Type', 'application/json');
this.http.post<string>(`http://127.0.0.1:8000/appculture`, culture, {
headers: headers
})
.subscribe(data => {
});
}
expressjs side:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
var path = require('path');
app.all("/*", function(req, res, next){
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
next();
});
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.post('/appculture', function (req, res) {
var currentCulture = `${req.body.text} from Nodejs`;
req.body.text = `${req.body.text} from Nodejs`;
res.send(req.body)
})
app.listen(8000, () => {
console.log('server started');
})
Either you are not sending anything of there is no value in body.text
Try to console.log(req.body) instead of req.body.text.
Try to console.log(culture) and this.getLangCookie() on the client side to see if you are actually sending something.
You can also make use of the network tab in the browser to inspect the request that you are sending.
Angular side:
callServer() {
const culture = this.getLangCookie().split("-")[0];
const headers = new HttpHeaders()
headers.set('Authorization', 'my-auth-token')
headers.set('Content-Type', 'application/json');
this.http.get(`http://127.0.0.1:8000/appculture?c=` + culture, {
headers: headers
})
.subscribe(data => {
});
}
Nodejs side:
app.get('/appculture', function (req, res) {
currentCulture = req.query.c;
res.send(req.body)
})
I'm having a problem with my Firebase Functions https request.
This is my code to trigger it:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.setHeader('Content-Type', 'application/json');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST");
next();
});
app.use((err, req, res, next) => {
if (err instanceof SyntaxError) {
return res.status(400).send();
};
next();
});
app.post('/fetchPosts', (req, res) => {
exports.fetchPosts(req, res);
});
exports.widgets = functions.https.onRequest(app);
const cors = require('cors')({ origin: true })
exports.fetchPosts = (req, res) => {
console.log(req.body)
console.log(res)
let topics = req.body.topics || ['live'];
let start = req.body.start || 0;
let num = req.body.num || 10;
let next = start+num;
// setting up the response.
});
That looks good as far as I can tell..
Now when I do my api call I do:
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Content-Type', 'application/json; charset=UTF-8');
const request = new RequestOptions({ headers: headers });
const url = 'https://my-link.cloudfunctions.net/widgets/fetchPosts';
let payload = {
topics: ["live", "pets"]
}
console.log(JSON.stringify(payload))
this.http.post(url, JSON.stringify(payload), request)
.pipe(map((res:Response) => {
console.log(res.json())
}))
.subscribe(
data => console.log(data),
err => console.log(err),
() => console.log('Got feed')
);
and it just returns topics with just ['live'].. because of the failsafe that I set up on the backend.. but why isn't getting my topics that I'm sending?
Also, when I console.log(req.body) on the backend it just shows {}.. an empty object..
Any ideas why the req.body doesn't seem to work? I do it with start and num as well, but they all revert back to the failsafe.
You must use POST method to handle req.body . In your case, you can handle your variable with req.query
To handle req.body . You can use Postman, then select POST method and post data as JSON . You can read more to use Postman well.
My app.js has the following:
const express = require('express');
const app = express();
const userRoutes = require('./api/routes/users');
// middleware - takes info passed in through the body
app.use(express.urlencoded({extended: false}));
app.use(express.json());
// middleware - adds headers to allow CORS.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if(req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT, POST, DELETE, GET');
res.status(200).json({});
}
next();
});
// middleware - filter all requests for users to the userRoutes
app.use('/api/v1/users', userRoutes);
// middleware - catch any requests that aren't caught by previous filters
app.use((req, res, next) => {
const error = new Error('No route found');
error.status = 404;
next(error);
});
// middleware - catch any errors that happen other places in the application (DB, etc.)
app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: { message: error.message }
});
});
module.exports = app;
and my userRoutes looks like this:
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
const gtrController = require('../controllers/gtrController');
const DAL = require('../DAL/dal');
router.get('/:userName', (req, res, next) => {
userController.getUser(req.params.userName, DAL.findOne, gtrController.getUser)
.then((result) => {
res.status(200).json(result);
})
.catch((error) => {
console.log(error);
res.status(500).json({ Error: { message: error }})
});
});
router.get('/:userName/games', (req, res, next) => {
userController.getUserStuff(req.params.userName, () => {}, gtrController.getUserStuff)
.then((result) => {
res.status(200).json(result);
})
.catch((error) => {
console.log(error);
res.status(500).json({ Error: { message: error }})
});
});module.exports = router;
If I check / and /username in Postman, I get 200's and all is right. However, when I try /username/games, I get a 404. I'm not sure why it's not hitting my userRoutes. I'm assuming it's my app.use, but I'm not finding any relevant documentation.
Thanks a bunch.
Figured it out, I think. My router.get('/:userName/games) should be router.get('/:userName\/games')
I am trying to set a nodejs rest api with SQL Server. I managed to make my GET method to work, but the PUT doesn't respond at all. I call the PUT method with postman like this: http://localhost:8080/api/user/1?firstname=John. What I am doing wrong?
var express = require("express");
var bodyParser = require("body-parser");
var sql = require("mssql");
var app = express();
// Body Parser Middleware
app.use(bodyParser.json());
// CORS Middleware
app.use(function (req, res, next) {
// Enabling CORS
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
// Setting up server
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
// Initiallising connection string
var dbConfig = { ... };
//Function to connect to database and execute query
var executeQuery = function(res, query) {
new sql.ConnectionPool(dbConfig).connect().then(pool => {
return pool.request().query(query)
}).then(result => {
let rows = result.recordset
res.setHeader('Access-Control-Allow-Origin', '*')
res.status(200).json(rows);
sql.close();
}).catch(err => {
res.status(500).send({ message: "${err}"})
sql.close();
});
}
// GET API
app.get("/api/user/:id", function(req , res, next) {
var query = "Select * from TestTable where id= " + req.params.id;
executeQuery (res, query);
});
// PUT API
app.put("/api/user/:id", function(req , res, next) {
var query = "UPDATE TestTable SET firstname= " + req.body.firstname + " WHERE Id= " + req.params.id;
executeQuery (res, query);
});
Your request handler handles the body of the request.
app.put("/api/user/:id", function(req , res, next){
// req.body is the body of the request
// req.query is the query parameters in the URL ( like ?firstname=1 )
var query = "UPDATE TestTable SET firstname= " + req.body.firstname + " WHERE Id= " + req.params.id;
executeQuery (res, query);
});
In order for your request to work you need to provide a proper PUT request containing JSON body. A curl version would look like :
curl -H 'Content-Type: application/json' \
-X PUT \
-d '{"firstname": "John"}' \
http://localhost:8080/api/user/1
I am building a simple api in node and express with postgre as Db following a tutorial.I am still learning and new to this tech.I followed everything as said and gave full permission to postgre thinking about issue with my db.But when i check it with postman i am getting this error Invalid Status Code : 0
my server.js
var express = require('express');
var logger = require('morgan');
var bodyParser = require('body-parser');
var api = require('./api/index');
var app = express();
///////////////////////
// Server Middleware
///////////////////////
app.use(logger(app.get("env") === "production" ? "combined" : "dev"));
// parse application/json
app.use(bodyParser.json());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// CORS
// This allows client applications from other domains use the API Server
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
//////////////////
// API Queries
//////////////////
app.use('/', api);
//////////////////
// Server Setup
//////////////////
app.set("env", process.env.NODE_ENV || "development");
app.set("host", process.env.HOST || "0.0.0.0");
app.set("port", process.env.PORT || 8080);
app.listen(app.get("port"), function () {
console.log('\n' + '**********************************');
console.log('REST API listening on port ' + app.get("port"));
console.log('**********************************' + '\n');
});
////////////////////
// Error Handlers
////////////////////
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status( err.code || 500 )
.json({
status: 'error',
message: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500)
.json({
status: 'error',
message: err.message
});
});
module.exports = app;
queries.js
var promise = require('bluebird');
var options ={
promiseLib : promise
};
var pgp = require('pg-promise')(options);
var connectionString = 'postgres://localhost:5432/star';
console.log(connectionString);
var db = pgp(connectionString);
function getAllStarships(req, res, next) {
db.any('SELECT * FROM starships')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved all starships'
});
})
.catch(function (err) {
return next(err);
});
}
module.exports ={getAllStarships: getAllStarships,};
index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.status(200)
.json({
status: 'success',
message: 'Live long and prosper!'
});
});
var db = require('./queries');
router.get('/api/starships', db.getAllStarships);
module.exports = router;
Querying Db is working fine from the pgadmin editor and returning the table.
Sample DB
DROP DATABASE IF EXISTS startrek;
CREATE DATABASE startrek;
\c startrek;
CREATE TABLE starships (
ID SERIAL PRIMARY KEY,
name VARCHAR,
registry VARCHAR,
affiliation VARCHAR,
launched INTEGER,
class VARCHAR,
captain VARCHAR
);
INSERT INTO starships (name, registry, affiliation, launched, class, captain)
VALUES ('USS Enterprise', 'NCC-1701', 'United Federation of Planets Starfleet', 2258, 'Constitution', 'James T. Kirk');
Any Help Appreciated.
Thanks.
Got this..Problem was with Authentication.Modified my query.js with
var db = pgp({
host: 'localhost',
port: 5432,
database: 'star',
user: 'postgres',
password: 'pes'
});
And it worked.