Home > OS >  Code not being executed - Mongoose - Cannot set headers after they are sent to the client
Code not being executed - Mongoose - Cannot set headers after they are sent to the client

Time:04-24

I'm trying to see if the userlookUp in the User.prototype.userExists function is true based on the UserChema.findOne() but for some unknown reason, the block is not being executed if its true. In this case, return this.errors.push('User already exists'), is not being executed.

I have some other error checks in another function, and they work great as they are supposed to (being shown in the browser console) except this one.

Looking for some help.

I appreciate it.

userController.js

const User = require('../models/User');

exports.login = function () {};
exports.logout = function () {};
exports.register = function (req, res) {
    let user = new User(req.body);
    user.register();
    if (user.errors.length) {
        res.send(user.errors);
    } else {
        res.send(user);
        res.send('Congrats, there are no errors.');
    }
};
exports.home = function (req, res) {
    res.send('API up and running!');
};

User.js

const validator = require('validator');
const UserSchema = require('./UserSchema');
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');

let User = function (data) {
    this.data = data;
    this.errors = [];
};

User.prototype.cleanUp = function () {
    if (typeof this.data.username != 'string') {
        this.data.username = '';
    }
    if (typeof this.data.email != 'string') {
        this.data.email = '';
    }
    if (typeof this.data.password != 'string') {
        this.data.password = '';
    }

    // get rid of any bogus properties

    this.data = {
        username: this.data.username.trim().toLowerCase(),
        email: this.data.email.trim().toLowerCase(),
        password: this.data.password,
    };
};

User.prototype.validate = function () {
    if (this.data.username == '') {
        this.errors.push('You must provide a username.');
    }
    if (
        this.data.username != '' &&
        !validator.isAlphanumeric(this.data.username)
    ) {
        this.errors.push('Username can only contain letters and numbers.');
    }
    if (!validator.isEmail(this.data.email)) {
        this.errors.push('You must provide a valid email.');
    }
    if (this.data.password == '') {
        this.errors.push('You must provide a password longer than 6 characters.');
    }
    if (this.data.password.length > 0 && this.data.password.length < 6) {
        this.errors.push('The password must be longer than 6 characters.');
    }
    if (this.data.password.length > 50) {
        this.errors.push('The password cannot exceed 50 characters.');
    }
    if (this.data.username.length < 3 && this.data.username.length > 15) {
        this.errors.push('The username must be at least 3 characters.');
    }
};

User.prototype.userExists = async function () {
    try {
        let userLookUp = await UserSchema.findOne({
            email: this.data.email,
        });
        if (userLookUp) {
            return this.errors.push('User already exists');
        } else {
            const avatar = gravatar.url(this.data.email, {
                s: '200',
                r: 'pg',
                d: 'mm',
            });

            userLookUp = new UserSchema({
                username: this.data.username,
                email: this.data.email,
                password: this.data.password,
                avatar: avatar,
            });

            const salt = await bcrypt.genSalt(10);

            userLookUp.password = await bcrypt.hash(this.data.password, salt);

            await userLookUp.save();
        }
    } catch (e) {
        console.log('there is a server problem');
    }
};

User.prototype.register = function () {
    // Step #1: Validate user data
    this.cleanUp();
    this.validate();
    this.userExists();

    // Step #2: See if user exists

    // Step #3: Get users gravatar

    // Step #4: Encrypt the password

    // Step #5: Return jsonwebtoken
    // Step #6: Only if there are no validation errors
    // then save the user data into a database
};

module.exports = User;

CodePudding user response:

In the User.register function you run some functions that are promises (async functions) which are not fulfilled before the User.register function returns.

You can do something like this:

User.prototype.register = async function () {
    this.cleanUp();
    this.validate();
    await this.userExists();
};

...

exports.register = async function (req, res) {
    let user = new User(req.body);
    await user.register();
    if (user.errors.length) {
        res.send(user.errors);
    } else {
        res.send(user);
        res.send('Congrats, there are no errors.');
    }
};
  • Related