0

I'm learning to create web applications using Express.js. In the process, we tried to implement a feature to prevent users from accessing certain pages when they are not logged in.

//  teamController.redirectView : Redirect the screen according to res.locals.redirect
app.get('/user/:id/team/member', teamController.showMember, teamController.redirectView)
//  The following is a middleware function written in another file(teamController.js)
showMember: (req, res, next) => {

  //  I want to set the redirect to the '/login' and skip the following process when no user are logging in.
  if(!res.locals.loggedIn) {
    res.locals.redirect = 'login'
    next()
  }

  // access the property that is set only when the user logs in
  let userID = res.locals.currentUser.userID

  //  Other processes...

When I accessed the URI when the user was not logged in, I was indeed taken to the login page, but I got the following error in the console.

TypeError: Cannot read property 'userID' of undefined
    at //  the position of 'let userID...'
Error occured: TypeError: Cannot read property 'userID' of undefined
    //  Abbreviated below...

Does this mean that excuting next() does not skip the following process, like 'return' does? Or is there some fatal error that is causing this error? Can you please help me?

I could have avoided the error by enclosing all subsequent processes in 'else', but if there is a better way, I would appreciate it if you could tell me that too.

NullDev
  • 6,739
  • 4
  • 30
  • 54
tayu
  • 23
  • 5

2 Answers2

1

You must use return next() or the code keeps executing after you call next()

J Livengood
  • 2,729
  • 1
  • 12
  • 26
  • Thanks for your answer! The code now works as expected. I didn't have the idea of returning a value in middleware. – tayu Mar 07 '21 at 05:26
1

Does this mean that executing next() does not skip the following process, like 'return' does?

Exactly. Calling next() alone doesn't stop further execution.
This is actually intentional because it allows for additional logic without making the client wait longer (especially with multiple middle-wares).

However to solve your problem, you can combine your next() and a return:

if(!res.locals.loggedIn) {
  res.locals.redirect = 'login';
  return next();
}

This way you don't have to warp all the code below in an else.
It's a common practice as well, as described here.

NullDev
  • 6,739
  • 4
  • 30
  • 54
  • Thanks for your answer and help with posting question! I didn't have the idea of returning some kind of value or function in the middleware. What are the other possible cases of 'return' in middleware? – tayu Mar 07 '21 at 05:37
  • @tayu Well, one is that your middle ware stops execution. The other one is that you actually return values (for example a status) to your controller. – NullDev Mar 07 '21 at 16:23
  • @tayu If you found an answer helpful, please consider [accepting it](https://stackoverflow.com/help/accepted-answer) :) – NullDev Mar 09 '21 at 10:29
  • Sorry, I haven't been able to return your comments for a long time. Thank you for your response. I'll accept it! – tayu Apr 20 '21 at 14:27