2

I am using nodejs and mysql2. I am storing all my queries inside a class. When I console.log the results I am able to view the data correctly, however when I use a return statment to return the data, I am getting undefined. I believe I need to use promises, but am uncertain how to do so correctly. Here is what I have currently which is returning undefined,

    viewManagerChoices() {
        const sql = `SELECT CONCAT(first_name, ' ',  last_name) AS manager, id FROM employee WHERE manager_id IS NULL`;
        db.query(sql, (err, rows) => {
        if (err) throw err;
           const managers = rows.map(manager => ({ name: manager.manager, value: manager.id }));
           managers.push({ name: 'None', value: null });
           return managers;
        });
    };

This is my attempt at using promises which is returning as Promise {<pending>},

viewManagers() {
        return new Promise((resolve, reject) => {
            const sql = `SELECT CONCAT(first_name, ' ',  last_name) AS manager FROM employee WHERE manager_id IS NULL`;
            db.query(sql,
                (error, results) => {
                    if (error) {
                        console.log('error', error);
                        reject(error);
                    }
                    const managers = [];
           for (let i = 0; i < results.length; i++) {
               managers.push({ name: results[i].manager, value: i+1 });
           }
           managers.push({ name: "None", value: null });
                    resolve(managers);
                }
            
            )
        })
        
    }

My class is called Query and I am calling these methods by doing,

const query = new Query();
query.viewManagerChoices();
query.viewManagers();
dev_in_training
  • 333
  • 5
  • 16
  • 1
    You can view promise results with `.then()` or `await`. Something like this: `query.viewManagers().then(result => console.log("Done:", result));`. – code Feb 26 '22 at 19:58
  • I don't to console.log the result. I want to return the result so I can use it elsewhere. – dev_in_training Feb 26 '22 at 20:08
  • Then use await. Create an async function (`async function funcName() {...}`) and inside do `const result = await query.viewManagers();`. – code Feb 26 '22 at 20:10

1 Answers1

0

Your implementation for viewManagers is correct however promises don't make calls synchronous.

Either you need to use then callback or await the result in async context.

const query = new Query();
query.viewManagers().then((managers) => {
  // do stuff here
}).catch((error) => console.error(error.message));

or

async someFunc() {
  const query = new Query();
  try{
    const managers = await query.viewManagers();
  }catch(error){
    console.error(error.message);
  }
}

Once you use promise you cannot just get a returned value without async/await or then flag. Once it's a promise the flow continues as the original.

For example:

// This is promise too because it has async flag.
// You cannot make it sync if you use promise in it
async myFunc(){ 
  const const query = new Query();
  const managers = await query.viewManagers();

  return managers;
}
// It actually returns Promise<...>

// Now if you want to use myFunc in another function 
// You need to do it the same way again
async anotherFunc(){ 
  const something = await myFunc();

  return something; // Returns promise
}

You can read more about promises here

n1md7
  • 2,854
  • 1
  • 12
  • 27
  • 1
    Thank you for your response. I want to be able to return the managers. So if I keep the viewManagers function within the class as it is and create the async function (I am doing this in another file) like this, ``` async function seeManagers() { const query = new Query(); try{ const managers = await query.viewManagers(); return managers; } catch (err) { console.log(err); } }``` I am still getting Promise { } – dev_in_training Feb 26 '22 at 20:18
  • 1
    Yes, anything flagged `async` is a promise. Once promise always promise :) . Wherever you reference that you need to use `then` or `await`. You cant make asynchronous operation sync. – n1md7 Feb 26 '22 at 20:21
  • 1
    How do I get it to actually show the data from managers when returning instead of Promise { }? To test this I am doing console.log(seeManagers); I tried it as this too, const query = new Query(); const myManagers = query.viewManagers().then((managers) => { return managers; }).catch((error) => console.error(error.message)); – dev_in_training Feb 26 '22 at 20:33
  • 1
    Updated the answer. I understand what you want but you can't do that. Once the promise is involved it's not sync anymore. – n1md7 Feb 26 '22 at 20:46