I'm building a web app with Node.js, mongodb, express and jade. When I start the server all is well on the terminal but when I load the webpage it returns a server error regarding a jade template...can you help?
error at /
{ [TypeError: /Users/Web/views/layout.jade:11
9| section.login
10| ul
>11| if session.isLoggedIn
12| li
13| a(href="/logout") Logout
14| else
Cannot read property 'isLoggedIn' of undefined]
Looking at my code on the layout.jade and login.js where I have all the codeI can't find the error. And this is following the exact structure and code of a course I recently followed.
layout.jade
html5
html
head
title= pageTitle
body
header
h1= pageTitle
a(href="/") Home
section.login
ul
if session.isLoggedIn
li
a(href="/logout") Logout
else
li
a(href="/login") Login
li
a(href="/signup") Create Account
section.content
block content
login.js
var mongoose = require('mongoose');
var Member = mongoose.model('Member');
var cleanString = require('../helpers/cleanString');
var hash = require('../helpers/hash');
var crypto = require('crypto');
module.exports = function (app) {
app.get('/signup', function (req, res) {
res.render('signup.jade');
});
// create a new account
app.post('/signup', function(req, res, next) {
var email = cleanString(req.param('email'));
var pass = cleanString(req.param('pass'));
if (!(email && pass)) {
return invalid();
}
Member.findById(email, function (err, member) {
if (err) return next(err);
if (member) {
return res.render('signup.jade', { exists: true });
}
crypto.randomBytes(16, function (err, bytes) {
if (err) return next(err);
var member = { _id: email };
member.salt = bytes.toString('utf8');
member.hash = hash(pass, member.salt);
Member.create(member, function (err, newMember) {
if (err) {
if (err instanceof mongoose.Error.ValidationError) {
return invalid();
}
return next(err);
}
//member created successfully
req.session.isLoggedIn = true;
req.session.member = email;
controle.log('created member: %s', email);
return res.redirect('/');
});
});
});
function invalid() {
return res.render('signup.jade', { invalid: true});
}
});
}
Express does not expose the request object req to the view. You'll have to manually provide these values to the view for example by a middleware like this
app.use(function(req, res, next) {
if (req.user) {
req.locals.isLoggedIn = req.session.isLoggedIn;
req.locals.member = eq.session.member;
}
next();
});
Express copies the req.locals to the oject available in the view's context. In your jade view you can now access member and isLoggedIn:
html5
html
head
title= pageTitle
body
header
h1= pageTitle
a(href="/") Home
section.login
ul
if isLoggedIn
li
a(href="/logout") Logout
else
li
a(href="/login") Login
li
a(href="/signup") Create Account
section.content
block content
I strongly recommend to not expose the full session object to the view but only the fields you really need.
If you want session to be available to the jade template as "session", you need to store it as res.locals.session.
http://expressjs.com/4x/api.html#res.locals also shows how to make a simple middleware that will do this for every page.