1

I have 2 functions in javascript and I want to set a global variable in a callback and then return it from my main function. I know javascript is async by nature so what would be the best way to do this? I have the code below:

var results="";

function getData() {

var sql = require("mssql");
var dbConfig={
        server:"server",
        database: "db",
        user:"user",
        password: "pw"
}




        var conn = new sql.Connection(dbConfig);
        var req = new sql.Request(conn);
        conn.connect(function (err){
                if (err) {
                console.log(err);
                return;
                }


                req.query("SELECT * FROM table",resultsCallback)

                conn.close();
        });

    return results;
}

function resultsCallback (err, recordset) {

        var tableify = require('tableify');

        if (err) {
                console.log(err);
        }
        else {

                var html = tableify(recordset);
                html = html.replace('<table>','');
                html = html.replace('</table>',');
                results=html;

        }
};
4
  • What exactly is not working and how should it work? Commented Apr 29, 2018 at 22:16
  • results is undefined since javascript is async. The return statement is executed before the callback function is even finished. How would I be able to wait for the callback to finish before returning results (ensuring results is defined before returning it)? Commented Apr 29, 2018 at 22:27
  • How is results undefinded and not ""? Commented Apr 29, 2018 at 22:29
  • Sorry that is what I meant. results is empty and was not returned containing the data from the html variable in the resultsCallback function. I set results equal to html Commented Apr 29, 2018 at 22:38

1 Answer 1

1

There is no right way to do this, because what you want to do is not right. You are trying to return a value before it was fetched. And you are using global variable, which can be dangerous for your code.

I understand why you are trying to use global variable to get the results from your callback, but it can't work.

When your code return results; executes, the SQL query has not even started, so it returns "".

Instead, use Promise:

function getData() {
    return new Promise((resolve, reject) => {
        var sql = require("mssql");
        var dbConfig = {
            server: "server",
            database: "db",
            user: "user",
            password: "pw"
        }
        var conn = new sql.Connection(dbConfig);
        var req = new sql.Request(conn);
        conn.connect(function (err) {
            if (err) {
                console.log(err);
                reject(err);
                return;
            }
            req.query("SELECT * FROM table",
                (err, recordset) => {
                    // Here we call the resolve/reject for the promise
                    try {
                        // If the results callback throws exception, it will be caught in 
                        // the catch block
                        resolve(resultsCallback(err, recordset));
                    }
                    catch (e) {
                        reject(e);
                    }
                }
            );

            conn.close();
        });
    })
}

function resultsCallback(err, recordset) {
    var tableify = require('tableify');
    if (err) {
        console.log(err);
        throw err;
    }
    else {
        var html = tableify(recordset);
        html = html.replace('<table>', '');
        html = html.replace('</table>', '');
        return html;
    }
};

Global variables can be dangerous, you don't need them. Promise solves your problem. You can have as many callbacks nested, but you always return value from Promise using resolve. This is the standard modern way to do this in JavaScript.

Usage:

getData().then((data)=>{console.log("Table data:",data);})
         .catch((error)=>{console.log("ERROR LOADING SQL:",error);})

Or, in an async function:

async function doSomethingWithData() {
    console.log("Start loading data.");
    const data = await getData();
    console.log("Done loading data.");
    // your results are in the data variable now
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your help. I understand most of your answer but where is data coming from in getData().then((data)=>{console.log("Table data:",data);})? should I fill that in with the variable name from the callback function? @GiulioBambini When I run it, it is still saying: Table Data: undefined

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.