skip to Main Content

when running the app and testing the /signup route the data gets written to the db and i can console.log it from the database/models.js file, but in the routes/index.js file it returns "Something went wrong." and postman shows nothing, not even an empty array or object.

routes/index.js

var express = require('express');
var router = express.Router();
const database = require('../database/models');


router.post('/signup', function(req, res, next) {
    if (!req.body.email || !isValidEmail(req.body.email))
        res.status(400).send('Email invalid.');
    else if (!req.body.username || !isValidCredential(req.body.username) || !req.body.password || !isValidCredential(req.body.password))
        res.status(400).send('Username/password invalid.');
    else {
        const result = database.createUser(req.body.email, req.body.username, req.body.password);
        if (result)
            res.status(200).send(result);
        else 
            res.send('Something went wrong.');
    }
});

function isValidEmail (email) {
    if (email.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"))
        return true;
    else
        return false;
}

function isValidCredential (credential) {
    if (credential.length < 6)
        return false;
    else if (credential.match(/^[a-z0-9]+$/i))
        return true;
    else
        return false;
}

module.exports = router;

database/models.js

const tools = require('./tools');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    email: String,
    username: String,
    hashedPassword: String,
    salt: String,
    accessToken: { type: String, default: "" }
});


const User = mongoose.model('User', userSchema);


function createUser(email, username, password) {
    const hashPass = tools.generatePassword(password);
    const newUser = new User({
        email: email,
        username: username,
        hashedPassword: hashPass.hash,
        salt: hashPass.salt
    });

    newUser.save(function (error, result) {
        if (error)
            return handleError(error);
        return { email: result.email, username: result.username };
    });
}

module.exports.createUser = createUser;

2

Answers


  1. Chosen as BEST ANSWER

    I figured it out.

    in routes/index.js use async/await like this:

    router.post('/signup', async function(req, res, next) {
        try {
            if (!req.body.email || !isValidEmail(req.body.email))
                res.status(400).send('Email invalid.');
            else if (!req.body.username || !isValidCredential(req.body.username) || !req.body.password || !isValidCredential(req.body.password))
                res.status(400).send('Username/password invalid.');
            else {
                const result = await database.createUser(req.body.email, req.body.username, req.body.password);
                if (result)
                    res.status(200).send(result);
                else 
                    res.status(403).send(result);
            }
        } catch (error) { return error; }
    });
    

    and in database/models.js use async/await as well, but also rewrite mongoose methods into ones without callbacks, with returns into variables, like this:

    async function createUser(email, username, password) {
        try {
            const hashPass = tools.generatePassword(password);
            const newUser = new User({
                email: email,
                username: username,
                hashedPassword: hashPass.hash,
                salt: hashPass.salt
            });
    
            const result = await newUser.save();
            return { email: result.email, username: result.username };
        } catch (error) { console.log (error); return error; }
    }
    

  2. In your code you are not returning anything when calling the createUser function. Here a couple of considerations:

    // index.js
    const result = database.createUser(req.body.email, req.body.username, req.body.password);
    

    since the createUser is an operation performed on a database, it will be probably asynchronous, and therefore also its result. I suggest the usage of async/await to be sure of the returned result. Also, you need to change the code of your models.js file to return a Promise and await for it.

    function createUser(email, username, password) {
        const hashPass = tools.generatePassword(password);
        const newUser = new User({
            email: email,
            username: username,
            hashedPassword: hashPass.hash,
            salt: hashPass.salt
        });
    
        return new Promise((resolve, reject)=> {
            newUser.save(function (error, result) {
                if (error) reject(error);
                resolve({ email: result.email, username: result.username });
            });
        });
    }
    

    and than you will have to await for your result. You can do it in the following way:

    // index.js
    // Add async here
    router.post('/signup', async function(req, res, next) {
        // ...other code
        // Add await here
        const result = await database.createUser(req.body.email, req.body.username, req.body.password);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search