Click here to Skip to main content
16,022,060 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
i'm just starting some nodejs mysql programming right now and yet hitting my first issues. I liked my program to check before inserting whether username and email is already in use and if skip inserting. For that i thought i could simply write two queries after another. My "return ..." in all queries always run into an error. "header to a closed client" something like that. So played around to solve it.
For my understanding javascript has it's eventloop where all lets say function are somehow registered and invoked successively. So my called function "authentication" is on the loop first this function was some queries which "db.connect, db.query, db.query and db.query" placed after. So my eventloop looks like that

authentication
db.connect
db.query
db.query
db.query

So authentication ends and then db.connect starts working???
I'm usually programming in c/c++ so it's new for me.

The console output
[nodemon] starting `node app.js`
Server started on Port 5000
Server started on Port 5000
[Object: null prototype] {
name: 'Huhu',
email: 'abc@xyz.com',
password: '1',
passwordConfirm: '1'
}
After Queries: 0
MYSQL connected in authentication
email in use
name in use
[
'Huhu',
'$2b$10$Izhe85NxinEEY0IXjUJQbu6dJto0l0AkWdBuG/t1bzITGMVcosaam',
'abc@xyz.com'
]
Got new user registered

Thanks all for answering

What I have tried:

JavaScript
import mysql from 'mysql';
import dotenv from 'dotenv';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import cookie from 'cookie-parser';
import util from 'util';

const sql = "INSERT INTO users (`username`, `password`, `email`) VALUES (?)";

dotenv.config({
    path: './.env'
});

function seachforEmail(db,email) {

    return new Promise((resolve,reject) => {
        db.query('SELECT email FROM users WHERE email = ?', [email], ( error, results ) => {
            if(error)
                reject(error);

            if(results.length > 0) {
                resolve(email);
            } 
            else {
                resolve(null);           
            }
        });        
    });
}

function seachforName(db,name) {

    return new Promise((resolve,reject) => {    
        db.query('SELECT username FROM users WHERE username = ?', [name], ( error, results ) => {
            if(error)
                reject(error);

            if(results.length > 0) {
                resolve(name);
            } 
            else {
                resolve(null);           
            }
        });       
    });
}

async function authentication(req,res) {
    console.log(req.body);

    if (req.body.password === req.body.passwordConfirm) {
        const salt = 10;
        var error_messages = [];
        const promises = [];
        const { name, email, password, passwordConfirm } = req.body;

        const db = mysql.createConnection({
            host: process.env.DATABASE_HOST,
            password: process.env.DATABASE_PASSWORD,
            user: process.env.DATABASE_USER,
            database: process.env.DATABASE
        });
        
        db.connect( async (error) => {
            if(error) {
                console.log(error);  
                return res.render('register', {message: 'connection failed'});              
            }
            else {
                console.log("MYSQL connected in authentication");    
                

                const db_email = await seachforEmail(db,email);
                console.log(db_email);
                if(db_email === email) {
                    console.log("Email in use");
                    return res.render('register', {message: 'Email in use'});    
                }
                else{
                    console.log("Email OK");                    
                }

                const db_name = await seachforName(db,name);
                console.log(db_name);
                if(db_name === name) {
                    console.log("Name in use");
                    return res.render('register', {message: 'Name in use'});    
                }
                else{
                    console.log("Name OK");                    
                }
                  
                bcrypt.hash(password.toString(), salt, (err, hash) => {
                    if(err)
                        return res.render('register', {message: 'Error for hashing password'});
                    
                    const values = [
                        name,
                        hash,
                        email
                    ];
            
                    console.log(values);  
                    
                    db.query('INSERT INTO users (`username`, `password`, `email`) VALUES (?)', [values], (err,data) => {
            
                        if(err) {
                            console.log("Register in failed");            
                            return res.render('register', {message: 'Inserting data failed'});        
                        }
                          
                        console.log("Got new user registered");

                        db.end();    
                        return res.render('register', {message: 'Inserting Success'});  
                    }) 

                })
            }
        })


    }
    else {
        return res.render('register', { message: 'Passwords not match' });
    }
}

export default authentication;
Posted
Updated 1-Oct-24 20:20pm
v4

1 solution

I'm not sure the problem is anything to do with this code. If the problem you are seeing is something like "you cannot set headers after they have been sent to a client", the problem is at the code that is calling this code. Without seeing that code, we can't really help you any further.
 
Share this answer
 
Comments
Code_bro 3-Oct-24 3:55am    
Hi, thanks for answering.
I have updated my code and with that it do work. But question is is this the right way. Async/await wil, for my understanding, stop the eventloop and block until my yet queries are finished. But i'm guessing this is not the correct way. For instance when multiple users want to get registered some of them will be blocked for a time too long to be convenient. So my question is how to handle this kind of task. Going away from async/await to chaining callback???

Thanks in advance
Pete O'Hanlon 3-Oct-24 9:53am    
As you are using Node, you'll probably be relieved to know that the way it works is that Node hands off to an event driven model here. This means that you can handle potentially 000s of connections (resource dependent of course), because the work is handed to separate threads which "signal" when they are ready to complete.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900