Reputation: 295
I've got a small Node/Express app that simply displays data on a page from several Postgres tables. My database connection/querying function lives in a separate file (db.js) as do my queries (queries.js). My question is how best to handle variable scope in my calls to the db connection function.
Here's an example:
// Module imports
var express = require('express');
var router = express.Router();
var config = require('../lib/config');
var db = require('../lib/db');
var queries = require('../lib/queries');
// GET /
router.get('/', function(req, res) {
db.dataTalk(queries.qOne, null, config.aws, function(err, result) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
var qOneResults = result;
}
db.dataTalk(queries.qTwo, null, config.aws, function(err, result) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
var qTwoResults = result;
}
res.render('index', {
title: 'Page Title',
qOneResults: qOneResults,
qTwoResults: qTwoResults
});
});
});
return;
});
My linter displays a warning on line 29 saying that qTwoResults is out of scope. If I want to display more data on a page, and need to make more database requests in a given route, what's the best way to call that function while maintaining proper scope?
Upvotes: 0
Views: 271
Reputation: 707476
It's probably a misleading error. var
declarations are automatically hoisted to the top of their containing function so qTwoResults
always exists at the point you are using it and it is in scope for the entire function. But putting the declaration inside a block and then using it outside of that block is just bad form (something linters often tell you about).
It may also be referring to the fact that you've declared and initialized qTwoResults
inside an if
block that may or may not get called before you try to use the value which isn't technically a script error, but is usually bad form.
Also, whenever you call res.render()
, you need to return
so you don't keep executing the rest of your code and subsequently try to call render again.
I'd suggest this code block that makes the following changes:
res.render()
once.Code:
// GET /
router.get('/', function(req, res) {
db.dataTalk(queries.qOne, null, config.aws, function(err, qOneResults) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
db.dataTalk(queries.qTwo, null, config.aws, function(err, qTwoResults) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
res.render('index', {title: 'Page Title', qOneResults, qTwoResults});
}
});
}
});
});
Upvotes: 1
Reputation: 2472
Your linter probably thinks it's out of scope, changing to to this should fix the issue:
// Module imports
var express = require('express');
var router = express.Router();
var config = require('../lib/config');
var db = require('../lib/db');
var queries = require('../lib/queries');
// GET /
router.get('/', function(req, res) {
var qOneResults, qTwoResults; // declare the variables here
db.dataTalk(queries.qOne, null, config.aws, function(err, result) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
qOneResults = result;
}
db.dataTalk(queries.qTwo, null, config.aws, function(err, result) {
if (err) {
res.render('error', {err: err, flavor: 'Having trouble talking to the database.', title: 'Error'});
} else {
qTwoResults = result;
}
res.render('index', {
title: 'Page Title',
qOneResults: qOneResults,
qTwoResults: qTwoResults
});
});
});
return;
});
Upvotes: 1