I am using Node and Express with the the mssql npm package to connect to an SQL Server database. I do this in my app.js
file which sets up a global
variable to create a connectionPool
to the database like so (I omitted some boilerplate stuff for brevity):
const mssql = require('mssql/msnodesqlv8'); // needs to use msnodesqlv8 driver for Windows Authentication to work
const express = require('express');
const app = express();
const DB_MYDB_Config = {
server: "localhost",
database: "MYDB",
options: {
trustedConnection: true // Windows auth enabled hence no username/password required
}
};
global.MSSQL_MYDB = new mssql.ConnectionPool(DB_MYDB_Config); //connectionPool available to whole app
I have a Model file called offer.js
which just does this:
async function getOffersAll() {
await MSSQL_MYDB.connect(); // connects to the database
try {
var result = await MSSQL_MYDB.request(MSSQL_MYDB).query('SELECT Top(1) * FROM [dbo].[Offer]');
return result; // returns the recordset of data
} catch (error) {
console.log(error);
} finally {
if (MSSQL_MYDB){
try {
await MSSQL_MYDB.close(); // closes the DB connection
}
catch (error) {
console.log('Error closing connection');
}
}
}
}
exports.getOffersAll = getOffersAll;
So far so good. I then have a Controller file index.js
which doesn't really work (explained with comments):
var router = require('express').Router();
const Offer = require('../models/offer'); // the `offer.js` file
/* the function below works perfectly */
(async function () {
var rsOffersAll = await Offer.getOffersAll();
console.dir(rsOffersAll); // works great! recordset rsOffersAll is printed to console
})();
/* this is where it goes wrong even after commenting out the test function above */
router.get('/', async function(req, res) {
var rsOffersAll = await Offer.getOffersAll(); // this just hangs and eventually I get a login failed error for SQL Server.
console.dir(rsOffersAll);
res.render('index', { pagetitle: 'Homepage'}); // never renders
});
module.exports = router;
My question is why does the first async function()
that awaits a result from Offer.getOffersAll()
not fail, but the same async function placed within the router.get('/')
handler fails with a login error? If I remove the var rsOffersAll = await Offer.getOffersAll();
from the router.get('/')
handler then the page renders, but of course I have no data to pass to it.
The exact same thing happens even if I store the test function's value in a variable and try to put it in the router.get()
handler like this:
async function getOffersTest() {
return await Offer.getOffersAll();
}
router.get('/', async function(req, res) {
var rsOffersAll = await getOffersTest(); // still breaks
console.dir(rsOffersAll);
res.render('index', { pagetitle: 'Homepage'}); // still never renders
});
My ultimate question how do I fix this so it just works the way it should in that when the homepage is visited, the router waits for the data to be returned from the database and then I can pass it to my view or just print to the console if I want?