Router.use() requires middleware function but got a string? - node.js

I have looked on the forums and have tried fixing everything I could, but still can't seem to get it to work. I am wanting to use router instead of having to use app.get. I have another project in which I am doing the same thing and it works just fine. So I am a little confused as to why this one isn't working. Thank you very much.
Here is my app.js:
var express = require("express");
var app = express();
var indexRoutes = require("./routes/index.js");
app.use("view engine", "ejs");
app.use(express.static(__dirname + "/public"));
app.use("/", indexRoutes);
app.listen(process.env.PORT, process.env.IP, function() {
console.log("server started on port : " + process.env.PORT);
});
Here is the route I am using:
var express = require("express");
var router = express.Router();
var multer = require("multer");
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploads');
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({storage: storage}).single('userPhoto');
router.get("/", function(req, res) {
res.render("index");
});
router.post("/uploads", function(req, res) {
upload(req, res, function(err) {
if(err) {
return res.send("error uploading file");
}
res.end("file is uploaded");
});
});
module.exports = router;

This obviously isn't right:
app.use("view engine", "ejs");
It should be:
app.set("view engine", "ejs");
FWIW, if you closely look at the stack trace that accompanied the error, you would have found the exact line in app.js that triggered the error:
TypeError: Router.use() requires middleware function but got a string
at Function.use (/private/tmp/node_modules/express/lib/router/index.js:458:13)
at EventEmitter.<anonymous> (/private/tmp/node_modules/express/lib/application.js:220:21)
at Array.forEach (native)
at EventEmitter.use (/private/tmp/node_modules/express/lib/application.js:217:7)
at Object.<anonymous> (/private/tmp/t/app.js:5:5) <--- there!
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)

i think you have to change this line:
app.use("/", indexRoutes);
with this:
app.use(indexRoutes);
more infos here: TypeError: Router.use() requires middleware function but got a Object

change this
app.use("view engine", "ejs");
to
app.set("view engine",'ejs');

Related

nodeJS/Express TypeError : Cannot read property 'method' of undefined

Hello I am getting an error when trying to start my server. This is what it says :
D:\Other\Projects\Code\Powershell\shopping-cart\node_modules\express\lib\router\index.js:139
debug('dispatching %s %s', req.method, req.url);
^
TypeError: Cannot read property 'method' of undefined
at Function.handle (D:\Other\Projects\Code\Powershell\shopping-cart\node_modules\express\lib\router\index.js:139:34)
at router (D:\Other\Projects\Code\Powershell\shopping-cart\node_modules\express\lib\router\index.js:47:12)
at Object.<anonymous> (D:\Other\Projects\Code\Powershell\shopping-cart\app.js:7:39)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Module.require (internal/modules/cjs/loader.js:1044:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object.<anonymous> (D:\Other\Projects\Code\Powershell\shopping-cart\bin\www:7:11)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47
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 routes = require('./routes/index')(passport);
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var expressHbs = require('express-handlebars');
var mongoose =require('mongoose');
var app = express();
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var bodyParser = require('body-parser');
mongoose.connect('mongodb://localhost:27017/shopping', {useNewUrlParser: true, useUnifiedTopology: true});
mongoose.connection.on('error', err => {
throw 'failed to connect to MongoDB';
});
require('D:/Other/Projects/Code/Powershell/shopping-cart/config/passport.js');
// view engine setup
app.engine('.hbs', expressHbs({defaultLayout: 'layout', extname:'.hbs'}))
app.set('view engine', '.hbs');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({secret: 'mysupersecret', resave: false, saveUninitialized: false}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
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 my index.js file :
var express = require('express');
var router = express.Router();
var Product = require('D:/Other/Projects/Code/Powershell/shopping-cart/models/product');
var csrf = require('csurf');
//var passport = require('D:/Other/Projects/Code/Powershell/shopping-cart/config/passport.js');
var passport = require ('passport');
var csrfProtection = csrf();
router.use(csrfProtection);
/* GET home page. */
router.get('/', function(req, res, next) {
Product.find(function(err, docs) {
var productChunks = [];
var chunkSize = 3;
for (var i = 0; i < docs.length; i += chunkSize) {
productChunks.push(docs.slice(i, i + chunkSize));
}
res.render('shop/index', { title: 'Shopping Cart', products: productChunks });
});
});
router.get('/user/signup', function (req, res, next) {
res.render('user/signup', {csrfToken: req.csrfToken()});
});
router.post('/user/signup', passport.authenticate('local.signup', {
successRedirect: '/user/profile',
failureRedirect: '/user/signup',
failureFlash: true
}));
router.get('/user/profile', function(req, res, next) {
res.render('user/profile');
});
module.exports = router;
Any hints on what could be the issue? I checked the lines that are being mentioned in the thrown error and can not find anything that is broken, and I have also checked other questions on this error, none that helped me. Any help is appreciated , thanks!
From the stack trace, it looks like the problem is caused by this line:
var routes = require('./routes/index')(passport);
If you look in your routes/index.js, you are exporting a router with:
module.exports = router;
Well, the problem is that you can't call router(passport). That's not a legit way to use a router. I can't tell what you were really trying to do with that. I would assume you want to hook your routes into the app with something like:
app.use(routes)
But, maybe you had some other intention there. In any case, router(passport) isn't something you can do.
FYI, it is a very useful skill to learn how to read these stack traces. You're typically looking to start at the top of the stack trace and go down line by line until you find a line of code that's in your own source file (your code that triggered this). Then, go examine that exact line with the context of what the eventual error was and see if you can then see what's wrong with that line of code or with the parameters used in that line of code.

app.use() requires a middleware function in express-edge

I'm creating blog using node js and following this tutorial https://vegibit.com/node-js-blog-tutorial/ but now I stuck it gives me error on app.use('express-edge') here is my code
const path = require('path');
const expressEdge = require('express-edge');
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = new express();
mongoose.connect('mongodb://localhost:27017/node-blog', {
useNewUrlParser: true
})
.then(() => 'You are now connected to Mongo!')
.catch(err => console.error('Something went wrong', err))
app.use(express.static('public'));
app.use(expressEdge);
app.set('views', __dirname + '/views');
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
app.get('/', (req, res) => {
res.render('index');
});
app.get('/posts/new', (req, res) => {
res.render('create')
});
app.post('/posts/store', (req, res) => {
console.log(req.body)
res.redirect('/')
});
app.listen(4000, () => {
console.log('App listening on port 4000')
});
and my error looks like
[nodemon] starting node index.js
C:\Users\91762\Desktop\Blog\node_modules\express\lib\application.js:210
throw new TypeError('app.use() requires a middleware function')
^
TypeError: app.use() requires a middleware function
at Function.use (C:\Users\91762\Desktop\Blog\node_modules\express\lib\application.js:210:11)
at Object. (C:\Users\91762\Desktop\Blog\index.js:16:5)
at Module._compile (internal/modules/cjs/loader.js:945:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:962:10)
at Module.load (internal/modules/cjs/loader.js:798:32)
at Function.Module._load (internal/modules/cjs/loader.js:711:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:1014:10)
at internal/main/run_main_module.js:17:11
[nodemon] app crashed - waiting for file changes before starting...
Maybe the tutorial is out of date, newest version of express-edge does not export edge engine as default export, the package exports a object what includes config, engine.
You can follow package document if your node version support object destructuring.
...
const { engine } = require('express-edge');
...
app.use(engine);
...
Or, just change a little in your code:
app.use(expressEdge.engine); // instead of app.use(expressEdge);
Use it like a handler is the best choice.
app.use(expressEdge.engine);

Module not found error - NodeJS Express.JS

I'm trying to catch the post data from my form and when I'm done with processing I want it to render the index.html file again.
Although when I'm trying the code as displayed below, I get an error.
The error:
Error: Cannot find module 'html'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:20:18)
at new View (/Applications/XAMPP/xamppfiles/htdocs/controlpanel/node_modules/express/lib/view.js:81:14)
at Function.render (/Applications/XAMPP/xamppfiles/htdocs/controlpanel/node_modules/express/lib/application.js:570:12)
at ServerResponse.render (/Applications/XAMPP/xamppfiles/htdocs/controlpanel/node_modules/express/lib/response.js:1008:7)
at /Applications/XAMPP/xamppfiles/htdocs/controlpanel/server.js:14:9
at Layer.handle [as handle_request] (/Applications/XAMPP/xamppfiles/htdocs/controlpanel/node_modules/express/lib/router/layer.js:95:5)
at next (/Applications/XAMPP/xamppfiles/htdocs/controlpanel/node_modules/express/lib/router/route.js:137:13)
The code:
var express = require('express');
var session = require('express-session');
var app = express();
app.use('/public', express.static('public'));
app.use( express.static('public/html') );
app.post('/', function(req, res, next) {
console.log('start processing postdata...');
next()
});
app.all('/', function(req, res) {
res.render('html/index.html');
});
app.listen(2222);
Everything works fine for the GET method.
Only the POST request is causing this error.
What am I doing wrong?
Thanks in advance, Laurens
Here is the working code, you should use sendFile instead if render. Render is been used with views.
'use strict';
let express = require('express');
// let session = require('express-session');
let app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/public', express.static('public'));
app.use(express.static('public/html'));
app.post('/', function (req, res, next) {
console.log('start processing post data...');
next();
});
app.all('/', function (req, res) {
res.sendFile('./index.html', {
root: __dirname + '/public/html'
});
});
app.listen(2222);

TypeError: Cannot read property 'databaseName' of undefined

I've been banging my head against the wall. I've been doing the lynda.com tutorail on essential Node.js and I'm stuck at this point.
When i type nodemon server.js I get the error. I'm having problems exporting the db connection in node.js. Any hints? Is there a better way to debug then make a change and refresh in Node?
/Users/khebert/Sites/node/airline/node_modules/connect-mongo/lib/connect-mongo.js:87
this.db = new mongo.Db(options.mongoose_connection.db.databaseName,
^
TypeError: Cannot read property 'databaseName' of undefined
at new MongoStore (/Users/khebert/Sites/node/airline/node_modules/connect-mongo/lib/connect-mongo.js:87:60)
at module.exports (/Users/khebert/Sites/node/airline/app.js:22:10)
at Object.<anonymous> (/Users/khebert/Sites/node/airline/server.js:4:27)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
2 Jan 08:04:56 - [nodemon] app crashed - waiting for file changes before starting...
db.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/flights', function(err) {
if (err) console.log(err);
else console.log('DB success');
});
module.exports = mongoose.connections;
server.js
var http = require('http'),
flights = require('./data'),
db = require('./db'),
app = require('./app.js')(flights, db);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
app.js
module.exports = function(flights, db) {
/**
* Module dependencies.
*/
var express = require('express');
var MongoStore = require('connect-mongo')(express);
var routes = require('./routes')(flights);
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({
secret: 'keyboard cat',
store: new MongoStore({
mongoose_connection: db
})
}));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(function (req, res, next) {
res.set('X-Powerd-By','Flight Tracker');
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' === app.get('env')) {
app.use(express.errorHandler());
}
app.get('/flight/:number', routes.flight);
app.put('/flight/:number/arrived', routes.arrived);
app.get('/list', routes.list);
app.get('/arrivals', routes.arrivals);
return app;
};
It might be a problem with the 'express.bodyParser()', you have to define your connections AFTER all the configuration of your app.
In db.js,
module.exports = mongoose.connections;
change to:
module.exports = mongoose.connections[0];
You can just reuse the db object already instantiated by mongoose!
new MongoStore({
db: mongoose.connection.db
})

nodeJS + express + jqtpl + app.engine

I've an issue in NodeJS, i'm new to this.
I'm using nodeJS, express and JQTPL to follow a tutorial about calling the github API but the problem is on the Application configuration, particularly on engine definition.
var express = require('express'),
app = express(),
...
;
app.configure(function(){
app.set('view engine', 'html');
app.set('view options', {layout: false});
app.engine('.html', require('jqtpl').__express);
});
// When we go to the URL "/" we go the the index.html
app.get("/", function(req, res){
res.render("index");
});
app.get("/board", function(req, res) {
res.render("board");
})
the app.engine call fail, here is the error :
if ('function' != typeof fn) throw new Error('callback function required');
^
Error: callback function required
at Function.app.engine (/var/lib/stickshift/51d5872b5973ca8338000033/app-root/data/547742/node_modules/express/lib/application.js:173:38)
at Function. (/var/lib/stickshift/51d5872b5973ca8338000033/app-root/data/547742/app.js:15:9)
at Function.app.configure (/var/lib/stickshift/51d5872b5973ca8338000033/app-root/data/547742/node_modules/express/lib/application.js:392:61)
at Object. (/var/lib/stickshift/51d5872b5973ca8338000033/app-root/data/547742/app.js:12:5)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
I understand what's a callback.. etc.. but the only way to call app.engine i found is builded like this.
Thank you for your help !
jqtpl seems to be broken (at least the version in the NPM repo; the GH version might work better): it tries to determine the version of Express, but it uses a property (express.version) that doesn't exist anymore.
Here's a workaround:
var express = require('express');
var app = express();
app.configure(function(){
app.set('view engine', 'html');
app.engine('html', require('jqtpl/lib/express').render);
});
app.get("/", function(req, res){
res.render("index"); // this renders "views/index.html"
});
app.listen(3013);

Resources