1

Please see my code below: I am trying to assign the recordset to a variable, can use index.js to call this variable out.

I am able to console.log the recordset. But when I call this IIFE, it is always says undefined.

var mssql = require('mssql');
var dbcon = require('./dbcon');

var storage = (function () {

  var connection = new mssql.Connection(dbcon);
  var request = new mssql.Request(connection);
  connection.connect(function (recordset) {
    request.query('select getdate()', function (err, recordset) {
      console.dir(recordset);
    });
    connection.close();
  });

})();

module.exports = storage;

index.js

var storage = require('./storage');
"AMAZON.HelpIntent": function (intent, session, response) {
storage(function (recordset){

var speechOutput = 'Your result is '+recordset;
response.ask(speechOutput);
});

However, I can't get the recordset. I got "Your result is {object, object}. "

  • 1
    The IIFE has no `return` statement, so yes, it will return `undefined`. – nnnnnn Apr 05 '17 at 03:02
  • I suspect your real issue is you expect to see recordset synchronously - however the value is obtained asynchronously - see https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Jaromanda X Apr 05 '17 at 03:06
  • I understand I need to put return statement. But no matter where I put it. It still shows unintended. – Chongran Hao Apr 05 '17 at 04:23

1 Answers1

2

that's because the IIFE is executing right away, try returning a function instead and then executing that function when you import that module,

 var storage = (function(mssql, dbcon) {
     return function() {
         var connection = new mssql.Connection(dbcon);
         var request = new mssql.Request(connection);
         connection.connect(function(recordset) {
             request.query('select getdate()', function(err, recordset) {

                 console.dir(recordset);

             });

             connection.close();
         });
     }
 })(mssql, dbcon);

and I don't understand why you need the IIFE, why don't you just assign the function to the variable?

  • If you're trying to assign the variable "recordset" to "storage" then this will never work as "connection.connect" is an asynchronous function, and in that case you should think about callback functions or promises.

Update

Based on your request, here's an implementation with a callback function and how it's used

var mssql = require('mssql');
var dbcon = require('./dbcon');

var storage = function(callback) {
    var connection = new mssql.Connection(dbcon);
    var request = new mssql.Request(connection);
    connection.connect(function(recordset) {
        request.query('select getdate()', function(err, recordset) {
            if(!err && callback){
                callback(recordset);
            }
            connection.close();
        });
    });
}

module.exports = storage;


// --------------------------------------------------
// implementation in another module

var storage = require("module_path"); // (1)
var answer;
storage(function(recordset){          // (2)
    answer = recordset;
    console.log(answer);  // actual data,  (3) 
    // implement your logic here
});
console.log(answer);  // undefined    (4)
// --------------------------------------------------

How this code works:
- You start by calling the storage method and sending it a callback method.
- The whole point of the callback function is that you won't wait for the result, your code will actually continue working at the same time that the storage method is connecting to the database and trying to get the data, ans since db operations are much slower, line(4) will execute before line(3).
- The flow of work will be as follows:

  • line (1)
  • line (2)
  • line (4)
  • line (3) at sometime in the future when the data is retrieved from database

  • - To see this more clearly, try doing this at the last line,
    setTimeout(function(){console.log(answer);}, 3000);
    

    This will wait for sometime until the data comes back;

    Ayman El Temsahi
    • 2,600
    • 2
    • 17
    • 27
    • Thank you so much for your answer. I am trying to develop a node js which can be run by Lambda. I am trying to let the program send query to AWS database and get a answer back. Do you have any suggestion? Would you please provide a callback function example based on my code? Appreciate it! – Chongran Hao Apr 05 '17 at 04:19
    • @ChongranHao, I've added some code for you in the answer – Ayman El Temsahi Apr 05 '17 at 05:11
    • EI Temsahi in my index.js file. If I use console.log(recordset), it would appear. However, If i use var answer = recordset, then console.log(answer), if still shows undefined. Please suggest. – Chongran Hao Apr 05 '17 at 15:39
    • how are using it, can you show where you assign answer and where you console.log? – Ayman El Temsahi Apr 05 '17 at 15:46
    • EI Temsahi I updated the original question. Please see the index.js. – Chongran Hao Apr 05 '17 at 16:04
    • @ Ayman El Temsahi, Amazing learning today. Thank you. If I want to get the answer right away, are there other solutions? – Chongran Hao Apr 05 '17 at 16:20
    • It depends on the module that connects to the database, for example in nodejs, there is a method that reads from a file async and doesn't wait (uses callback functions) and there is another method that does the same thing but not async and waits for the answer. BTW, this way is much better and you should not avoid it, you can implement your code into small functions and put these functions inside the callback method. – Ayman El Temsahi Apr 05 '17 at 16:23
    • EI Temsahi, I updated the index.js again. I am trying to let AWS Lambda to execute my node.js code. And read the answer from my AWS SQL database. I got a answer "Your result is {object, object}. " Please help. Thank you. – Chongran Hao Apr 05 '17 at 17:26
    • @ChongranHao This way you have your data, I don't know what's in it. What you should do is console.log this response, investigate what the data contains and then use it as your logic requires. – Ayman El Temsahi Apr 05 '17 at 17:49