0

I would think this would be simple...however I am smashing my head against it. I am calling a function in my 'main' (Node.js) script to do a query on a Postgres database. I simply wish to return an array (or even better an 'array of arrays'), from the function so I can process those variables. The Postgres processing is handled in a different .js file...I would think this code should work, however it does not:

my database .js file ('queries.js'):

const config = {
...
//various settings
...
};

const Pool = require('pg').Pool;
const pool = new Pool(config);

const getUsers = function(request, response) {
 pool.query('SELECT * FROM users', (error, results) => {
  if (error) {
  throw error
  }

//    response.status(200).json(results.rows)

  return _findings = ["value1", "value2"];

  })
}

module.exports = {
getUsers
}

my 'main' script:

const db = require('./routes/queries');

app.get('/lookup', function (req, res) {

var _findings = [];
db.getUsers;

console.log("I FOUND A LOOKUP...!!!" + _findings[0] + _findings[1]);

});

I do not get errors however the returned array variables ('_findings') are reported as "undefined". I know the Postgres query is operative because if I 'un-comment' the "response.status(200).json(results.rows)" it returns the data properly. I want to be able to take the returned array variables into my calling function and then do additional processing from there. Is the problem caused by attempting to 'return' from a different .js file...? I thank you in advance for any suggestions.

OK based upon given advice I have made some modifications...the following code was inserted into my 'main' script...and it IS functional:

async function mytest() {

// create a new promise inside of the async function
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(true), 1000) // resolve
});

// wait for the promise to resolve
let result = await promise;

// console log the result (true)
console.log(result);
}

app.get('/lookup', function (req, res) {

mytest();

});

If I add the 'async' function to my database ('queries.js') file to perform the query:

async function getSingle(req, res) {

// create a new promise inside of the async function
let promise = new Promise((resolve, reject) => {

 pool.query('SELECT * FROM users', (error, results) => {
  if (error) {
  reject("db query failed");  //rejected
  }
  resolve(response.status(200).json(results.rows));  //fulfilled    
 })

});

// wait for the promise to resolve
let result = await promise;

}

However if I change my 'main' script as this:

app.get('/lookup', function (req, res) {

db.getSingle();

});

I get a "db.getSingle is not a function" error. Any help on proper syntax is appreciated on how to call the async database function...as well as if the actual async function is correct...I THINK it is...but I am new to the concept of 'promise/await/async'...thank you in advance.

OK...this code is actually working...! In my database ('queries.js') script I have:

function getFinals() {
 return new Promise(function(resolve, reject) {

  pool.query('SELECT * FROM users', (error, results) => {
   if (error) {
   reject(new Error('Ooops, something broke!'));
   } else {
   resolve(results.rows);
   }
  })  //pool.query

 }); 
}

In my main script I call:

app.get('/lookup', function (req, res) {

 db.getFinals()
 .then(function(value) {
 console.log('Async success!', value);
 })
 .catch(function(err) {
 console.log('Caught an error!', err);
 });

});

I actually get the data from the database query returned to my calling function...! I feel like I learned something today.

Also need to determine how to return an 'array of arrays' from the async function...that is probably tomorrow's project...

Thanks to all the responses I received...all great help and much appreciated!

Pangit
  • 564
  • 1
  • 7
  • 23
  • You should `db.getUsers()` instead of `db.getUsers`. You are not invoking your function. – Paul T. Rawkeen Nov 16 '19 at 21:19
  • Thank you for the response. The result is the same either way... I have also tried to pass the array variable as 'db.getUsers(_findings)' however it still returns 'undefined' after the call to the function. – Pangit Nov 16 '19 at 21:31
  • 1
    if `db.getUsers` is a database call then it's asynchronous and you aren't dealing with it that way at all. You need to call it and pass it at least a callback. Look at the api spec and see what is needed. – Chris Sharp Nov 16 '19 at 22:13
  • @Pangit, @Chris Sharp is right. You can return `Promise` from `getUsers()` and make `async (req, res) { const results = await db.getUsers() }`. Or pass a callback as Chris suggested. – Paul T. Rawkeen Nov 16 '19 at 22:23
  • Thank you both for your inputs. I am not familiar with using promises and async/await functions. I have made some changes...ran a successful test however still not entirely there yet...please see me updated edits above. Again thank you for your replies and I am sorry about not having familiarity with these concepts...learning something new here... – Pangit Nov 16 '19 at 23:37
  • 1
    OK I didn't 'export' those functions from the 'queries.js' file...so I have that cleared up now. – Pangit Nov 16 '19 at 23:47
  • does the 'let result = await promise;' in the async function ('getSingle') perform the 'return' back to the calling function? Or do I have to set an actual 'return' command there...? I placed "console.log("RESULT FROM ASYNC CALL: " + result);" into the end of the calling function however got an "ReferenceError: result is not defined" error... – Pangit Nov 16 '19 at 23:52
  • @Pangit You have to `return` explicitly to the calling function. And the call result will a promise, which you will have to `await` again (or use `.then()` on). – Bergi Nov 16 '19 at 23:54
  • Btw, the node-postgres library already returns promises, you don't need to promisify the callback version yourselves. Simplify to `exports.getSingle = async function() { return (await pool.query('SELECT * FROM users')).rows; }`. Then in the other module, use `app.get('/lookup', function (req, res) { db.getSingle().then(result => { res.status(200).json(result); }, error => { console.error(error); res.status(500).json({error: "sorry"}); }); });` – Bergi Nov 16 '19 at 23:58
  • Thanks @Bergi I will look into Postgres returning promises...I did not know that – Pangit Nov 17 '19 at 02:13
  • I think I have something that actually seems to work now. I have edit posted my working code at the end of my entries above. If anybody can notice any potential problems or errors with that code I would be thankful to know about it. I thank all of you that sent replies, it is much appreciated...! – Pangit Nov 17 '19 at 02:26
  • One more stupid question...how can I access the returned value in my calling script? I included a " for (_count = 0; _count < (value.length - 1); _count++) {console.log("count...!" + _count);}" loop within the ".then" statement however it is not being recognized or running...? – Pangit Nov 17 '19 at 03:17
  • You forgot to declare the `_count` variable somewhere (with `let` or `var`), and you probably want to iterate until `_count < value.length` (no `-1`), but I can't see why it wouldn't work otherwise. – Bergi Nov 17 '19 at 05:51
  • Yes I declared 'var _count' earlier in the code I just had it omitted in my post. I got that issue solved. Thank you for the response. – Pangit Nov 17 '19 at 17:40

0 Answers0