Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Damian McCarthy
Damian McCarthy
3,656 Points

My mongoose Schema variables are coming back undefined which making the hash not work.

This is my user.js I can view the json file and everything is there when I do res.send(req.body); but in here it is saying it is undefined, any ideas?

This is the error I am getting including the console log of the JSON strings

undefined
undefined
Error: data and salt arguments required
    at Object.hash (D:\Folder\Code\Nymadic\nymadic.com\node_modules\bcrypt\bcrypt.js:138:17)
    at model.UserSchema.pre (D:\Folder\Code\Nymadic\nymadic.com\models\user.js:37:12)
    at callMiddlewareFunction (D:\Folder\Code\Nymadic\nymadic.com\node_modules\kareem\index.js:427:23)
    at model.next (D:\Folder\Code\Nymadic\nymadic.com\node_modules\kareem\index.js:58:7)
    at _next (D:\Folder\Code\Nymadic\nymadic.com\node_modules\kareem\index.js:106:10)
    at process.nextTick (D:\Folder\Code\Nymadic\nymadic.com\node_modules\kareem\index.js:452:38)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const UserSchema = new mongoose.Schema({
    userName: {
        type : String,
        unique : true,
        required : true,
        trim : true
    },
    password: {
        type: String,
        required: true
    },
    firstName: {
        type: String,
        required: true,
        trim: true
    },

    lastName: {
        type: String,
        required: true,
        trim: true
    },
    email: {
        type : String,
        unique : true,
        required : true,
        trim : true
    }
});

// hash password before saving to database
UserSchema.pre('save', (next) => {
    const user = this;
    console.log(UserSchema.userName);
    console.log(UserSchema.password);
    bcrypt.hash(user.password, 10, (err, hash) => {
        if(err) {
            return next(err);
        }
        user.password = hash;
        next();
    })
});


const User = mongoose.model('User', UserSchema);
module.exports = User;

index.js file

const express = require('express');
const router = express.Router();
const User = require('../models/user.js')


// Home Routes

router.get('/', (req, res, next) => {
    res.render('index');
});

// About Routes

router.get('/about', (req, res, next) => {
    res.render('about', {title : '| About'});
});

// Tools Routes

router.get('/tools', (req, res, next) => {
    res.render('tools', {title : '| Tools'});
});

router.post('/tools', (req, res, next) => {
    var domain = req.body.domain;
    res.end(domain);
});

// Login Routes

router.get('/login', (req, res, next) => {
    res.render('login', {title : '| Login'});
});

router.post('/login', (req, res, next) => {
    res.send(req.body);
    res.end;
});

// Registration Routes 

router.get('/registration', (req, res, next) => {
    res.render('registration', {title : '| Registration'});
});

router.post('/registration', (req, res, next) => {
    res.send(req.body);
    // Check if all fields are filled
    if (req.body.userName && req.body.password && req.body.confirmPassword && req.body.firstName && req.body.lastName && req.body.email) {

        // Confirm Password is the same
        if ( req.body.password != req.body.confirmPassword) {
            const err = new Error ("Passwords don't match!");
            err.status = 400;
            return next(err);
        }

        const userData = {
            userName: req.body.userName,
            password: req.body.password,
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            email: req.body.email
        };

        // Use schema 'create' method to insert document into Mongo
        User.create(userData, (error, user) => {
            if (error) {
                return next(error);
            } else {
                return res.redirect('/profile');
            }
        });
    } else {
        const err = new Error("All Fields Required.");
        err.status = 400;
        return next(err);
    }
});

// Profile Routes

router.get('/profile', (req, res, next) => {
    res.render('profile');
});
module.exports = router;

app.js file

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const path = require('path');
const mongoose = require('mongoose');

// Mongodb connection
mongoose.connect("mongodb://localhost:27017/nymadic");
const db = mongoose.connection
// Mongo error
db.on('error', console.error.bind(console, 'connection error:'));

// Body Parser and Cookie Parser
app.use(bodyParser.urlencoded({ extended:false }));
app.use(cookieParser());

// Static Files
app.use(express.static(__dirname + '/public'));

// Pug Render Engine
app.set('view engine', 'pug');

// Routes
const mainRoutes = require('./routes');
const wikiRoutes = require('./routes/wiki');

app.use(mainRoutes);
app.use('/wiki', wikiRoutes);

app.listen(8080, () => {
    console.log('Nodejs is running on port 8080...');
  }); 
Damian McCarthy
Damian McCarthy
3,656 Points

That is what they do in the video. Also when I do what was suggested the User stops working because the information doesn't get to the database so i am not sure how it is possible that it is undefined but it still gets passed properly to mongo.

Damian McCarthy
Damian McCarthy
3,656 Points

Well that was what I was showing about is that it wasn't , where is says undefined twice those are the 2 items I am trying to console log.

1 Answer

Kyle Knapp
Kyle Knapp
21,526 Points

My mistake! I wasn't aware of that export syntax. I'm not sure what the exact issue is, but the stack trace is definitely pointing back to your bcrypt.hash function in your database file.

bcrypt.hash(user.password, 10, (err, hash) => {
        if(err) {
            return next(err);
        }
        user.password = hash;
        next();
    })

You may want to console.log(user.password) to make sure that user.password is returning the intended value.