3

Update:

I have a async function as follows:

async function userHandler(username, displayName, profilePicture, email) {
  connection = await connectDB()
    await connection.query('USE spyncdb;');
    await connection.query('SELECT * FROM users WHERE username = ?', [username], function(error, result, fields) {
      if (error) {
          console.log(error);
      }
      if (result) {
          if (result != 0) {
            console.log('User already in database')
            return result[0].user_id;
            // Do whatever should be done
            } else {
            // Add user to database
            connection.query('INSERT INTO users (username, displayname, profilePicture, email) VALUES (?, ?, ?, ?)', [username, displayName, profilePicture, email], function(error, result, fields) {
              if (error) {
                console.log('ERROR');
                console.log(error);
              }
              if (result) {
                console.log('user inserted into db');
                return;
              };
            })
            }
        }
    });
}

I then call this function, and want to store the return value from it (user_id).

I call the function from the following:

async () => {
    let user_id = await userHandler(aUser.username, aUser.displayName, 
    aUser.profilePicture, aUser.email);
    
     console.log(user_id);
}

But I only get "undefined" - why?

PS. I use the mysql library for my DB connection.

2 Answers 2

3

Ok so I finally managed to solve the issue. The main thing that had to be done was to switch from a callback-based code to the more modern async/away way to handle async code, this make the code much less complicated and easier to handle and read.

Also I switched from the mysql library to mysql2 library, which is more adapted to async functions. The final code looks like this:

const mysql2 = require('mysql2/promise');


// Connect to server
const pool = mysql2.createPool({
    host     : "ENDPOINT",
    user     : "USERNAME",
    password : "PASSWORD",
    port     : "3306",
    database : "DATABASENAME",
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// Function for checking the user in the database
async function checkUser(username, displayName, profilePicture, email) {
  const result = await pool.query('SELECT * from users WHERE username = ?', [username]);
  if (result[0].length < 1) {
    console.log('User not found, adding new user...');
    const newResult = await pool.query('INSERT INTO users (username, displayname, profilePicture, email) VALUES (?, ?, ?, ?)', [username, displayName, profilePicture, email]);
    return newResult[0].insertId;
  }
  console.log('User found in DB')
  return result[0][0].user_id;
}

// Calling the check function with the input values from the user
async function check() {
let user = await checkUser(aUser.username, aUser.displayName, aUser.profilePicture, aUser.email);
console.log(`user ID is: ${user}`);
}

// Invoking the check function      
check();
Sign up to request clarification or add additional context in comments.

Comments

0

There's two solutions. The easy one, don't use callbacks, use Promises and then:

aUser.user_id = await userHandler

Or you'll have to supply a callback function and synchronize your code accordingly:

function example(cb) {
  userHandler(..., function(result) {
    cb(user_id);
  });
}

example(function(user_id) {
  aUser.user_id = user_id;
});

Remember, callback-driven code is extremely not fun to implement and work with so if you can, pivot to Promises, if not full async/await.

The general rule here is if your function makes callbacks to get answers you must accept a callback you can chain on to. A return from a callback function is almost always thrown in the trash and ignored.

5 Comments

Thanks, I'm trying to wrap my head around this stuff and I realized that callbacks seem to be the older way of doing stuff and promises and sync/away is the way to go. I've updated the post with the function userHandler, because I can't really see how I should implement it to be able to get the user_id. I've tried your first suggestion but it didn't really work. Could you help me out again maybe?
It would be awesome to remake it to the await-structure if possible!
It really, really helps if you're using a Promise-capable library like Sequelize to interface with your database. As a back-up plan you can "promisify" callback functions with things like Bluebird to bridge that gap. I'm not sure what library you're using here, but if it supports Promises, then you can await and it makes life so much easier.
I'll look into that - but from what I read online the method I posted in the OP should work so that makes me a bit confused..
You need to be careful about async code. Ensure you're sequencing things properly. Try and use await on anything that happens "eventually", like query().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.