I've been writing my first node.js/express test web-app and faced a problem with routing (I think so, but I'm not sure) while developing. Here are some debug info about my problem. I'm using Express 4 and trying to connect router like this:
var router = express.Router();
...
app.use(router);
Error log:
TypeError: undefined is not a function
at /Users/user1/Documents/work/habitsapp-node-app/app.js:77:11
at Layer.handle_error (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/layer.js:71:5)
at trim_prefix (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:310:13)
at /Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:330:12)
at next (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:271:10)
at next (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/route.js:121:14)
at Layer.handle [as handle_request] (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/layer.js:97:5)
at next (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/layer.js:95:5)
at /Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:330:12)
at next (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/lib/router/index.js:271:10)
at SendStream.error (/Users/user1/Documents/work/habitsapp-node-app/node_modules/express/node_modules/serve-static/index.js:120:7)
at SendStream.emit (events.js:107:17)
app.js file
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var errorhandler = require('errorhandler');
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 config = require('config');
var mongoose = require('lib/mongoose');
var session = require('express-session');
var log = require('lib/log')(module);
var HttpError = require('error').HttpError;
var multer = require('multer');
var router = express.Router();
var app = express();
// view engine setup
app.engine('ejs', require('ejs-locals'));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static('public'));
var MongoStore = require('connect-mongo')(session);
app.use(session({
secret: config.get('session:secret'),
key: config.get('session:key'),
cookie: config.get('session:cookie'),
store: new MongoStore({mongoose_connection: mongoose.connection})
}));
app.use(require('middleware/sendHttpError'));
app.use(require('middleware/loadUser'));
app.use(router);
app.use(express.static(path.join(__dirname, 'public')));
require('routes')(app);
app.use(function(err, req, res, next) {
if (typeof err == 'number') {
err = new HttpError(err);
}
if (err instanceof HttpError) {
res.sendHttpError(err);
} else {
if (app.get('env') == 'development') {
app.errorHandler()(err, req, res, next);
} else {
log.error(err);
err = new HttpError(500);
res.sendHttpError(err);
}
}
});
var server = app.listen(config.get('port'), function () {
var host = server.address().address;
var port = server.address().port;
log.info('HabitTracker app listening on port ' + config.get('port'));
});
loadUser.js
var User = require('models/user').User;
module.exports = function(req, res, next) {
req.user = res.locals.user = null;
if (!req.session.user) return next();
User.findById(req.session.user, function(err, user) {
if (err) return next(err);
req.user = res.locals.user = user;
next();
});
};
This line of code should be
if (app.get('env') == 'development') {
app.use(errorhandler());
} else {
log.error(err);
err = new HttpError(500);
res.sendHttpError(err);
}
I'm not sure what you are doing here, but app.errorHandler is undefined. The () that follow app.errorHander cause your error message TypeError: undefined is not a function.
Also, you require errorhandler with this code var errorhandler = require('errorhandler');, but you reference it as errorHandler. Your casing doesn't match.
This has nothing to do with the express router or ejs.
Related
I'm trying to access my routes /api and /api/superheroes, but i'm getting this error when I do that.
Not Found
404
NotFoundError: Not Found
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\app.js:27:8
at Layer.handle [as handle_request] (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:317:13)
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:275:10)
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:47:12)
app.js
var api = require('./routes/api.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 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);
app.use('/api', api);
// 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;
api.js
var express = require('express');
var router = express.Router();
router.get('/superheros', function(req, res) {
res.send('Just a test');
});
module.exports = router;
I'm following a tutorial and I already saw from scratch again and I didn't found the solution. I just want to access the routes that I've created to continue the lesson. Someone can help me? What should I do?
You've got a typo: it says /superheros (heros, not heroes) in api.js. Also, under /api, you're mounting a Router instance that has exactly one route defined: /superheros. There's no / route in the Router that you pass to:
app.use('/api', api);
And so, there is no handler for /api + /.
I've been trying to fix this for 2 hours now and I'm getting a little frustrated. Basicly, I want to validate a form input, but I always get this error.
TypeError: req.checkBody is not a function
at C:\Users\bobbo\Desktop\Develops\Project_folder\routes\index.js:19:7
at Layer.handle [as handle_request] (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\bobbo\Desktop\Develops\Project_folder\node_modules\express\lib\router\index.js:47:12)
Pretty much the only info I could find is telling me to write the app.use(expressValidator());
after app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));, but it doesn't matter what I do, I still get the same error. Here is the code I use.
//index.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var expressValidator = require('express-validator');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressValidator());
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/signup', function(req, res, next) {
res.render('signup', { title: 'Express' });
});
router.post('/signup', function(req, res){
var name = req.body.name;
console.log(name); //works
req.checkBody("name", "Invalid name").notEmpty();
var errors = req.validationErrors();
if(errors){
console.log('errors');
} else{
console.log('no errors');
}
});
module.exports = router;
app.js
//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 bodyParser = require('body-parser');
var expressValidator = require('express-validator');
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');
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
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;
package.json
//package.json
{
"name": "pizzaonline",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "^1.18.3",
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.16.0",
"express-session": "^1.15.6",
"express-validator": "^5.2.0",
"http-errors": "~1.6.2",
"morgan": "~1.9.0",
"pug": "2.0.0-beta11"
}
}
If I comment out req.checkBody("name", "Invalid name").notEmpty();, the next express-validation code to be executed is var errors = req.validationErrors();, giving me an identical error telling me req.validationErrors() is not a function. I'm new to this but this tells me that express-validator is not properly installed, am I wrong? Any help is much appreciated. Thanks in advance.
In Your nested route files (index.js and users.js) You're creating new app instance and attaching that validator to it that in fact is not correct.
Cause by creating new app instance You create new app context that is different from app in app.js.
So here's the fix:
1) attach express validator above this lines in app.js file:
app.use(expressValidator());
app.use('/', indexRouter);
app.use('/users', usersRouter);
2) remove app object generation from nested route files and make it look like:
//index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
router.get('/signup', function(req, res, next) {
res.render('signup', { title: 'Express' });
});
router.post('/signup', function(req, res){
var name = req.body.name;
req.checkBody("name", "Invalid name").notEmpty();
var errors = req.validationErrors();
if(errors){
console.log('errors');
} else{
console.log('no errors');
}
});
module.exports = router;
npm i --save express-validator#4
reqiure app.js
app.use(expressValidator());
and try again
npm start
My express application seems to return 404 NOT FOUND whenever im using a post request method in my routes file. GET-requests are working fine and i can only see "GET" requests in the console aswell, even if im using a post request.
Is there some missing link between app.js and routes/index.js that might be causing this?
// routes/index.js
router.post('/foo', function (req, res, next) {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
})
// 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 index = require('./routes/index');
var app = express();
var cors = require('cors')
app.use(cors())
// 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(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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;
Result:
Not Found 404
Error: Not Found
at C:\Users\willow\Desktop\backend\app.js:29:13
at Layer.handle [as handle_request] (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:275:10)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:275:10)
at SendStream.error (C:\Users\willow\Desktop\backend\node_modules\serve-static\index.js:121:7)
What you wanna do should look like this in practice:
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
router.route('/foo')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
});
return router;
}
// 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')(express); // require routes at routes/index.js
var app = express();
var cors = require('cors')
app.use(cors())
// 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(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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;
What I usually do is create a function that expects express as param like this
(routes/index.js)
module.exports = (express) => {
// Create express Router
var api = express.Router();
// add routes
api.route('/some_endpoint')
.post((req, res) => {
res.json({ message : 'some message' })
});
return api;
}
then I just import this file to my app.js
like this
(app.js)
// set api as a middleware
const api = require('./routes')(express);
app.use('/api/v1', api);
that way I hook up my api and my server.
I am building an REST Api where it contains quite a few images using Express. The project structure is shown below.
And inside the public folder you can see that structure.
I want to upload images and store them inside the img folder. So here is my code.
fileupload.html
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="http://127.0.0.1:3000/fileupload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>
and fileupload.js
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var multer = require('multer');
//console.log(multer);
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/img'}));
app.get('fileupload.html', function (req, res) {
res.sendFile( __dirname + "/" + "fileupload.html" );
})
app.post('/fileupload', function (req, res) {
console.log(req.files.file.name);
console.log(req.files.file.path);
console.log(req.files.file.type);
var file = __dirname + "/img" + req.files.file.name;
fs.readFile( req.files.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if( err ){
console.log( err );
}else{
response = {
message:'File uploaded successfully',
filename:req.files.file.name
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
})
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at localhost:3000/", host, port)
})
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 mongoose = require('mongoose');
var url = 'mongodb://localhost:27017/larissaApp';
mongoose.connect(url);
var db = mongoose.connection;
db.on('error',console.error.bind(console,'connection error:'));
db.once('open',function(){
console.log("Connected correctly to server");
});
var routes = require('./routes/index');
var users = require('./routes/users');
var newsRouter = require('./routes/newsRouter');
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(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use( bodyParser.json({limit: '50mb'}) );
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true,
parameterLimit:50000
}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/news',newsRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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
});
});
}
// 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: {}
});
});
module.exports = app;
However after trying to upload an image from the html page,I get a 404 error.
404
Error: Not Found
at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\app.js:40:13
at Layer.handle [as handle_request] (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:275:10)
at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:317:13)
at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\express\lib\router\index.js:275:10)
at serveStatic (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modules\serve-static\index.js:75:16)
What am I doing wrong?
Thanks,
Theo.
Download the code for Uploading images using Express
File upload with express
Try this.
I modified your js little bit, it works for me without errors.
I've written comments for each line edited.
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var multer = require('multer');
//console.log(multer);
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: false}));
var upload = multer({dest: './img'});// declare multer default path(best to use /tmp for this if on linux)
app.get('fileupload.html', function (req, res) {
res.sendFile(__dirname + "/" + "fileupload.html");
});
app.post('/fileupload', upload.single('file')/*inserted multer middleware for one file*/, function (req, res) {
//Declare variable to easy change
var file = req.file;
// this are correct names for variables of req.file
console.log(file.filename);
console.log(file.path);
console.log(file.mimetype);
// path of file stored
var path = __dirname + '/img/';
// variable for storing path
var filePath = path + file.filename;
//It's better to declare variable first then use it
var response;
fs.readFile(filePath, function (err, data) {
fs.writeFile(path + file.originalname, data, function (err) {
if (err) {
console.log(err);
} else {
response = {
message: 'File uploaded successfully',
filename: file.originalname
};
}
console.log(response);
res.end(JSON.stringify(response));
});
});
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at localhost:3000/", host, port)
});
I'm trying to build a shopping cart using node.js, express.js and mongodb. I'm in the process of building the sign up functionality. My problem is when I try to access the localhost:3000/user/profile link I get this error message:
Failed to lookup view "/user/profile" in views directory
"/Users/vynguyen/shopping-cart/views
Error: Failed to lookup view "/user/profile" in views directory "/Users/vynguyen/shopping-cart/views"
at EventEmitter.render (/Users/vynguyen/shopping-cart/node_modules/express/lib/application.js:579:17)
at ServerResponse.render (/Users/vynguyen/shopping-cart/node_modules/express/lib/response.js:960:7)
at /Users/vynguyen/shopping-cart/routes/index.js:34:6
at Layer.handle [as handle_request] (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/layer.js:95:5)
at /Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:330:12)
at next (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:271:10)
at csrf (/Users/vynguyen/shopping-cart/node_modules/csurf/index.js:117:5)
at Layer.handle [as handle_request] (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:312:13)
at /Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:330:12)
at next (/Users/vynguyen/shopping-cart/node_modules/express/lib/router/index.js:271:10
)
The profile.hbs file is located in the right folder, but for some reason the server won't pull it up.
Here's the whole file structure:
enter image description here
Here's my index.js file:
var express = require('express');
var router = express.Router();
var csrf = require('csurf');
var passport = require('passport');
var Product = require('../models/product');
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;
Here's my 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 expressHbs = require('express-handlebars');
var mongoose = require('mongoose');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var routes = require('./routes/index');
var userRoutes = require('./routes/user');
var app = express();
mongoose.connect('localhost:27017/shopping');
require('./config/passport');
// view engine setup
app.set('views', __dirname+'/views');
app.engine('.hbs', expressHbs({defaultLayout: 'layout', extname: '.hbs'}));
app.set('view engine', '.hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({secret: 'mysupersecret', resave: false, saveUninitialized: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use('/user', userRoutes);
app.use('/', routes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 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;
When the view file path is resolved, the view path with leading slash will resolve to root directory and so the error. You need to resolve the view file relative to your views directory. Using user/profile or ./user/profile in res.render method would resolve the view file correctly.
correct code:
res.render('user/profile') or res.render('./user/profile')