So I've been looking for a solution for a while now and nothing works for my problem.
So I have a homepage ('/'), a profile page ('/profile') and a login/register page. I am using passport with local, twitter and google for accounts. What I want to do is display the users name and profile picture inside the navbar anywhere they go on the site.
This is what the partial looks like:
partials/_nav.hbs
{{#if isAuthenticated}}
<div class="dropdown">
<button type="button" class="btn btn-primary dropdown-toggle dropdown-button"
data-toggle="dropdown">
<img class="user-avatar" src="{{image}}" alt="{{username}}'s' avatar">{{username}}
</button>
<div class="dropdown-menu">
<a class="dropdown-item user-dropdown" href="/profile">My Profile</a>
<a class="dropdown-item user-dropdown" href="#">User Settings</a>
<a class="dropdown-item user-dropdown" href="/logout">Logout</a>
</div>
</div>
{{else}}
<a href="/register" class="account-button text-nowrap">Register/Login
</a>
{{/if}}
routes/index.js -- And to display the user name and image, on my routes page I have:
// Login
router.get('/', (req, res, user) => {
res.render('index', {
username: req.user.username, // <-- line 10 and if I remove this it goes to line 11
image: req.user.image,
});
});
// Profile
router.get('/profile', ensureAuth, (req, res) => {
res.render('profile', {
username: req.user.username,
image: req.user.image,
});
});
So now onto my problem. The homepage and profile route actually work and display the username and image. The problem is when I try to logout, when I try to logout I get this error:
TypeError: Cannot read property 'username' of undefined
at C:\Users\Desktop\Code\site\routes\index.js:10:20 // look in code above for this line
I have tried to solve this by instead passing the req.user object and then doing user.username for example inside my partial.
I'm kinda new to express but I think the problem may be that when I log out, username doesn't exist anymore and that's why it gives an error. However if that is the case, it should display the login/register button that's in my partial.
Just to note I registered isAuthenticated as a local variable in my server.js and if you need, this is my ensureAuth code:
middleware/auth.js
module.exports = {
ensureAuth: function (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
},
};
So I found out the solution. In my answer I was passing req.user.username without checking if it actually existed. So I asked on reddit and someone helped me come to this answer:
const { user: { username, image } = {} } = req;
What this does is it destructures the user object and either returns username and image, or nothing ({}).
The get request looks something like this:
router.get('/', (req, res) => {
const { user: { username, image } = {} } = req;
res.render('index', {
username,
image,
});
});