Error setting up simple server with middleware on node.js express - javascript

I am reasonably new to node express and am trying to set up a simple server with middleware to handle routing.
The error I'm getting is TypeError: Router.use() requires a middleware function but got a Object
The error is because of the app.get('/', require(routes)); line. Does anyone know what I need to put here as a middleware function?
//server.js
http = require('http');
let port = process.env.PORT || 3000;
let host = '127.0.0.1';
var express = require('express');
var app = express();
var routes = './api/routes/positions';
app.use('/', require(routes));
http.createServer(app).listen(port);
console.log('Listening at http://' + host + ':' + port);
//#########################
//positions.js
const express = require('express');
var router = express.Router();
router.get('/', (err, req, res, next) => {
res.status(200).json({
message: "hello from server"
});
});
module.exports.router;

You are exporting the module in wrong way from positions.js file.
you need to write
module.exports = router
instead of,
module.exports.router
What you have written will bind a new key router to exports object, but haven't assigned any value to it and hence it goes back to default the empty object {}.
Now express was expecting a function but got object and hence the error. You can verify it by checking the require(routes) in server.js file.
Update (advice)
Please study this formatted version of your code.
const http = require('http');
const express = require('express');
const routes = require('./api/routes/positions');
const port = process.env.PORT || 3000;
const host = '127.0.0.1';
const app = express();
app.use('/', routes);
http.createServer(app).listen(port);
console.log('Listening at http://' + host + ':' + port);
If you want to read more project, you can read this boilerplate written by me. It's bit old, but may serve you well.

#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('ag:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3002');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

Try this one:
//server.js
let port = process.env.PORT || 3000;
let host = '127.0.0.1';
var express = require('express');
var app = express();
var routes = require('./api/routes/positions');
http.createServer(app).listen(port);
console.log('Listening at http://' + host + ':' + port);
//#########################
//positions.js
const express = require('express');
var router = express.Router();
router.use('/', routes);
app.use('/', routes);
router.get('/', (err, req, res, next) => {
res.status(200).json({
message: "hello from server"
});
});
module.exports = router;

Related

how to set up a HTTPS server using express

I have an application using express.
I have a http server running but I would like to use a https server for more security.
I already generated my selfsigned.crt certificate and the key selfsigned.key using openssl (I'm on windows and I'm using visual studio code ).
however, after trying during hours I didn't succeed.
I checked a lot of websites and its seems doable but I can't do it.
(My project name is called carsapp that's why you will see it appears in the www file)
my app.js file :
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
and in my bin directory the www file :
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('carsapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
As you can see the http server works perfectly but I tried for https but I can't so here it is my code before trying for https.
You can enable https by including the https library and then pass the required certificates in as options, along with the express app.
const https = require('https');
const fs = require('fs');
const app = require('../app');
const options = {
key: fs.readFileSync('./keyFile.key'),
cert: fs.readFileSync('./certFile.crt')
};
const server = https.createServer(options, app);
server.listen(8000);
On a side note I happen to agree with #Quentin. If this app faces the world you might want to seriously consider using a reverse proxy.
I suggest making these changes to the 'www' file in your bin folder...
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('carsapp:server');
var https = require('https'); // <--- change to https
var fs = require('fs'); // <--- for loading the certificates
/** Load the certificate and key files using 'fs' */
const options = {
key: fs.readFileSync('./keyFile.key'),
cert: fs.readFileSync('./certFile.crt')
};
// The createServer function takes an extra argument.
var server = https.createServer(options, app);
// (continue with the rest of your code)

Why do I need to explicitly call app.listen(port) in order to make express-ws working?

I'm new to NodeJS Express, I was following the official tutorial from express-ws to setup websocket in the simple project generated by npx express-generator . In the app.js, I've to explicitly call the app.listen(3000) in order to make the ws connection working. Am I doing this correctly although it is working ? What's the difference between app.listen vs. server.listen in this case? what is app.set(port,port) in www.js used for?
app.js - I've to add the last line below:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var app = express();
var expressWs = require('express-ws')(app);
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
app.listen(3001)// for websocket listen port
www.js - this file was generated by the express-generator and I see it's already calling app.set('port',port) and server.listen(port)
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('xapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
The .listen(port) method on either a server object or on the Express app object is what actually starts your server so that it is listening for incoming requests. Without that, you don't have a running http server. And, you need a running http server for both Express and for your webSocket. If you don't call something that triggers server.listen(), then you won't have a running server. It will be all configured and waiting to start, but won't yet be running.
If you look at the code for app.listen(), it is just a helper function. All, it does is this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
It creates an http server object and then calls .listen() on it. It's just a shortcut. If you have a reason to want to create your own http server object and then call server.listen() on that one, you can do it that way too. In fact, if you're starting an https server, you have to do it that way because you have to pass the right arguments to https.createServer() which app.listen() doesn't do for you.

tried to upload my node.js app to heroku,it says Web process failed to bind to $PORT within 60 seconds of launch, Process exited with status 137

I tried to upload my node.js app to heroku, it says error is Web process failed to bind to $PORT within 60 seconds of launch, Process exited with status 137,how do I fix this
here is my app.js
require('dotenv').config();
const createError = require('http-errors');
const express = require('express');
const engine = require('ejs-mate');
const path = require('path');
//conscd t favicon = require('serve-favicon');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const passport = require('passport');
const bodyParser = require('body-parser');
const User = require('./models/user');
const session = require('express-session');
const mongoose = require('mongoose');
const methodOverride = require('method-override');
var MongoDBStore = require('connect-mongodb-session')(session);
//const seedPosts = require('./seeds');
//seedPosts();
//require routes
const index = require('./routes/index');
const posts = require('./routes/posts');
const app = express();
console.log(process.env.DATABASEURL);
//connect to database
var url = process.env.DATABASEURL || 'mongodb://localhost:27017/transfed'
mongoose.connect(url,{
useNewUrlParser: true ,
useUnifiedTopology: true,
useCreateIndex: true
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log("we're connected!");
});
var store = new MongoDBStore({
uri: 'process.env.DATABASEURI',
collection: 'mySessions'
});
// Catch errors
store.on('error', function(error) {
console.log(error);
});
i figured it might be from the bin file but i cant find the error.
heres what my bin file looks like
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('myapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
I used express generator to generate the skeleton of my app and am new to programming, what do I have to do to fix this issue?
First, I would try without the normalizePort() function. This is what I am using and it works perfectly:
var port = process.env.PORT || 5000;
I am not sure where you found your code but I would test with a simple example from the official documentation to make sure it works well:
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000
express()
.use(express.static(path.join(__dirname, 'public')))
.set('views', path.join(__dirname, 'views'))
.set('view engine', 'ejs')
.listen(PORT, () => console.log(`Listening on ${ PORT }`))
Finally, I would also check the Procfile and make sure it contains the right command.

How to setup clusters in expressjs 4.x app?

I have an expressjs generated app which is configured with socket io and I would like to implement nodejs clusters in it. The problem is that in Express 4.x the server listening configuration is in the bin/www file and no longer in app.js file.
Also my app is configured with socket io so I don't want to brake it too.
This is how it should be implemented in express apps according to this article:
app.js
// Include the cluster module
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
// Count the machine's CPUs
var cpuCount = require('os').cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) {
cluster.fork();
}
// Listen for dying workers
cluster.on('exit', function (worker) {
// Replace the dead worker, we're not sentimental
console.log('Worker %d died :(', worker.id);
cluster.fork();
});
// Code to run if we're in a worker process
} else {
// Include Express
var express = require('express');
// Create a new Express application
var app = express();
// Add a basic route – index page
app.get('/', function (request, response) {
console.log('Request to worker %d', cluster.worker.id);
response.send('Hello from Worker ' + cluster.worker.id);
});
// Bind to a port
app.listen(3000);
console.log('Worker %d running!', cluster.worker.id);
}
And this is what I have:
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var app = express();
var io = app.io = require('socket.io')();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
var players = {};
//socket io
io.on('connection', function(socket) {
socket.on('new player', function(data) {
var player = {
id: socket.id,
name: data.name,
color: data.color
}
players[socket.id] = player;
io.to(`${socket.id}`).emit('player info', player);
});
socket.on('chat', function(data) {
io.emit('message', {
player: players[data.id],
text: data.text
});
});
socket.on('disconnect', function() {
delete players[socket.id];
});
});
module.exports = app;
bin/www
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('elvin:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '80');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = app.io
io.attach(server);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, function(){
console.log('server listening on port ' + server.address().port);
});
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
What do I do? The module.exports = app; is what it is causing me troubles
I use my own boiler plate. I used socket, cluster and express together in it. Here is a link to it.
Desktop-CHAT-app
You can download it and make the changes over here and proceed. I've used many useful packages too.
Hope it helps!

app.set('port', port) 'TypeError: undefined is not a function'. Beginner, need ideas

I'm an amateur learning to build with node.js. I've been following a tutorial to create my first node.js app. It worked perfectly until I entered 'npm start'. The log is:
C:\node\nodeteest3\bin\www:16
TypeError: undefined is not a function
at Object.<anonymous> M+<C;\node\nodetest3\bin\www:16:5
at Module_compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.module.runMain (module.js:501:10)
at startup(node.js:129:16)
at node.js:814:3
Then it output about 20 lines starting with "npm ERR! " + filepaths, that I don't think are necessary, as the error seems to be in the bin file. The code for this is
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('nodetest3:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
This is where the error points to:
[app.set('port', port);]
-------^error pointer at 's'-so clearly about set------------
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
Like I said in the beginning, I'm a complete beginner with command-line/github, but I'm already in love with it. I try to practice it every night after I finish my homework, and am getting really frustrated about getting stuck because I haven't been able to move forward for four days now. Also, I'm running this on node.js and the OS is Windows 8. Anything helps! Let me know if you want me to post any of the other code; I omitted so as to not add more than necessary.
"../app (app.js file) JUST ADDED"***************************
../app file:
[ App.js ]
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
var app = express();
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json({estended: true}));
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser({extended:true}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
You are not exporting anything in the app.js file. At the end of app.js file, include following line.
module.exports = app;
See whether your problem goes away.
And one more addition: you have var app = express(); twice in your app.js.
You don't have declared any function called set inside the app.js file.
Create that function and export it like this:
exports.set = function(...) { ... };
If this app is the express app yo especify a port like this:
var express = require('express'),
http = require('http');
var app = express();
http.createServer(app).listen(port);
instead of
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
This is because the port is a property of the http server and not of the express app
You can use also
var express = require('express'),
app = express();
app.listen(port);
Intaned of calling export please use module.export end the end of your script.
exports = app;
module.exports = app;
At the bottom of your app.js:
app.set('port', process.env.PORT || 26398); //<--- replace with your port number
// Server
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports = app;
In my case I simply moved the normalizePort function before the function was called. This was in coffeescript but I've converted it to javascript here.
normalizePort = function(val) {
var port;
var port;
port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
};
port = normalizePort(process.env.PORT || '4000');
Just add "module.exports=app;" in the app.js file.

Categories

Resources