0

So, I wanted to move all my mysql query functions to another file and import it as a module, but I'm having trouble in that the function is returning undefined.

index.js:

const express = require('express')
const https = require('https');
const fs = require('fs');
const dbx = require('./databaseconn');

var options = {
    key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
    cert: fs.readFileSync('/etc/letsencrypt/live/example.com/cert.pem'),
    ca: fs.readFileSync('/etc/letsencrypt/live/example.com/chain.pem')
};

const app = express();

app.use(express.json());

app.use(function(req,res,next) {
    if (req.body.action) {
        switch (req.body.action) {
            case "login":
                var user = req.body.username;
                var pass = req.body.password;
                console.log(dbx.checklogin(user, pass));  // This prints undefined
                break;
            default:
                break;
        }
    }
});

https.createServer(options,app).listen(8000);

databaseconn.js:

const mysql = require('mysql');

exports.checklogin = function(username, password) {
    var connection = mysql.createConnection({
        host     : 'localhost',
        user     : 'root',
        password : 'xxxxxxxxxxxxxx',
        database : 'users',
    });

    connection.query('select * from logins where username = ? and password = ?;',
    [
        username,
        password
    ], function (err, rows, fields) {
        if (err) throw err;
        if (!rows.length) {
            console.log('0');
            return {"success":0};
        } else {
            console.log('1');      // THIS PRINTS
            return {"success":1};  // So this should return the JSON
        }
    })
}

So I see a "1" from the console.log in the databaseconn.js, but the console.log in the index.js file is printing undefined. What am I doing wrong? I also did a super barebones test that works fine so I can't see the difference.

test.js:

const express = require('express');
const test2 = require('./test2');
var t = test2.test();
console.log(t);

test2.js:

exports.test = function() {
    return {"success":1};
}
Wyllow Wulf
  • 410
  • 4
  • 23
  • @Bergi it's not because of async because (!rows.length) evaluates as false – Wyllow Wulf Apr 19 '19 at 22:05
  • I figured out my best solution: pass the response object to the module function and respond directly there. works! – Wyllow Wulf Apr 19 '19 at 22:38
  • That `(!rows.length)` line is inside the asynchronous callback that you are trying to `return` from. The duplicate explains at length why that doesn't work. – Bergi Apr 20 '19 at 07:59

2 Answers2

2

console.log statement inside index.js module prints undefined because checklogin function inside databaseconn.js module does not return anything ({"success":1} is the return value of the inner anonymous function inside checklogin, but it is not a return value of checklogin itself).

Should you want to handle query result inside index.js module, you can pass a callback from index.js to databaseconn.js module, it may look like as follows:

index.js:

app.use(function(req, res, next) {
  if (req.body.action) {
    switch (req.body.action) {
      case "login":
        var user = req.body.username;
        var pass = req.body.password;
        dbx.checklogin(user, pass, function(err, rows, fields) {
          console.log('Here you can handle the query result')
        });
        break;
      default:
        break;
    }
  }
});

databaseconn.js:

exports.checklogin = function(username, password, callback) {
  var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : 'xxxxxxxxxxxxxx',
    database : 'users',
  });

  connection.query('select * from logins where username = ? and password = ?;',
    [
      username,
      password
    ], callback)
}
antonku
  • 7,377
  • 2
  • 15
  • 21
  • Why does it not return anything? I KNOW that's a seperate question lol... In the test example it does return the JSON, so I dont know whats different – Wyllow Wulf Apr 19 '19 at 21:31
  • 1
    The thing is that `return {"success":1};` is a return value of an anonymous function that is inside `checklogin`. But `checklogin` itself does not have it's own return value. In the test example function that is exported has a return statement, that makes the difference. – antonku Apr 19 '19 at 21:34
  • but test.js prints {"success":1} so why does that work but the other doesn't, it's the same – Wyllow Wulf Apr 19 '19 at 21:35
  • 1
    @Willdorf `test` returns in the first level itself. The `spl-connection query` called inside checklogin accepts a callback, which will be called to push the query result and you are only returning within the callback. – Thirueswaran Rajagopalan Apr 19 '19 at 21:44
1

It looks like you're returning {"success":1} from connection.query but the checklogin function itself isn't returning anything?

Try

const mysql = require('mysql');

exports.checklogin = function(username, password) {
    var connection = mysql.createConnection({
        host     : 'localhost',
        user     : 'root',
        password : 'xxxxxxxxxxxxxx',
        database : 'users',
    });

    return connection.query('select * from logins where username = ? and password = ?;',
    [
        username,
        password
    ], function (err, rows, fields) {
        if (err) throw err;
        if (!rows.length) {
            console.log('0');
            return {"success":0};
        } else {
            console.log('1');      // THIS PRINTS
            return {"success":1};  // So this should return the JSON
        }
    })
}
Jenn A
  • 11
  • 2