Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript User Authentication With Express and Mongo Sessions and Cookies Creating the Profile Route and Page

'next' is not defined. Error in my user.js file.

So I have been working with the user login authentication and everything works beautifully except when I try to log in as a user that does not exist. I keep getting an error that says 'next' is not defined (ReferenceError: next is not defined).

I should stress, my login is working. I can compare passwords / emails, I can throw the error if they don't match. I just get this error if I try to sign in with an email that has not been registered yet. Funny how I keep sweating the small things but I do know the importance of solid error pages to keep the flow of an application moving.

Kind of at a loss as to how this is happening but I will try to debug it. Extra eyes always help but here are the blocks of my application that seem to be throwing the error.

user.js (model for mongo)

UserSchema.statics.authenticate = function(email, password, callback){
    User.findOne({ email: email}).exec(function(error, user) {
        if (error) {
            return callback(error);
        } else if (!user) {
            var err = new Error("A profile does not exist with the email used.");
            err.status = 401;
            // This seems to be where the 'next' method is not defined...
            return next(err);
        }
        bcrypt.compare(password, user.password, function(error, result) {
            if (result === true) {
                return callback(null, user);
            } else {
                return callback();
            }
        });
    });
}

index.js (contains my routes)

// GET /login
router.get('/login', function(req, res, next) {
    return res.render('login', {title: 'Log In'});
});

// POST /login
router.post('/login', function(req, res, next) {
    if (req.body.email && req.body.password) {
        User.authenticate(req.body.email, req.body.password, function(error, user){
            if (error || !user) {
                var err = new Error("Email or password are incorrect.");
                err.status = 401;
                return next(err);
            } else {
                req.session.userId = user._id;
                return res.redirect('/profile');
            }
        });
    } else {
        var err = new Error("Email & password are required.");
        err.status = 400;
        return next(err);
    }
});

I guess I am just confused as to how the 'next' function is undefined if it is used elsewhere in the application. Tried following word for word what Dave did and I am sure that since I am human, I missed something and would appreciate if someone can help me find what I missed. Will keep trying to figure this out.

Sorry for being the weirdo who is not satisfied with the app working, but wants it to break properly too...

Thanks to everyone who can help!

1 Answer

Neil McPartlin
Neil McPartlin
14,662 Points

Hi Benjamin. You have nearly solved this yourself. In user.js, just below your comment in green, note that you are within the UserSchema.statics.authenticate function having the parameters email, password & callback (but not next). So below your comment, replace return next(err) with return callback(err) and this will help.

Thank you! I feel like a dunce because that makes complete sense. I appreciate the extra pair of eyes! That was it!