Reputation: 327
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;
Upvotes: 1
Views: 2431
Reputation: 8225
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')
Upvotes: 1