Vipul Mehra Vipul Mehra - 1 month ago 8
Javascript Question

Javascript variable undefined even after defining in Express Js, mongo db

Lately I have started experimenting with Node.js and Express.js. I am building a micro-application which takes in the data from Mongo Db and displays using Jquery datatables in the front-end using server-side example.

I am able to get the required data. But whenever I restart the application, I am not able to get total count of the records and variable comes out to be undefined. After again reloading the page I get the count. Somehow being new to javascript It seems I am making some mistake related to variable scoping or accessing variables inside functions. So to solve it I even created call backs in the express js app. Some of the functions are working and some are not. Here is the code that fetches the count in the document:

//calling the functions here in the express js app
app.get('/tweets/', function(req, res){
var countWithoutFilters;
var countTwitter;
var page = parseInt(req.query.start);
var limit = parseInt(req.query.length);
var skip = page;
var searchQuery = {};
searchQuery = req.query.search.value;
searchQuery = (searchQuery == '' || searchQuery == undefined) ? {}:searchQuery;
var searchId = parseInt(searchQuery);
countNumberOfRowsInTweets(function(data){
countWithoutFilters = data;
});
countNumberOfRowsInTweetsAfterFilters(searchQuery, function(data) {
countTwitter = data;
});
queryTweetsCollection(searchQuery, limit, skip, function(data){
res.send({
draw: req.query.draw,
recordsTotal: countTwitter,
recordsFiltered: countTwitter,
data: data,
page: parseInt(page)
});
});

});

//function to get tweets from the document and count the length
function countNumberOfRowsInTweets(callback)
{
db.collection('tweets').find().toArray(function(err, result){
if(err)
return console.log(err);
callback(result.length);
});
}
//count the items after applying filters
function countNumberOfRowsInTweetsAfterFilters(searchQuery, callback)
{
console.log("Filtered row:"+searchQuery);
var searchId = parseInt(searchQuery);
db.collection('tweets').find({ $or: [{text: new RegExp(searchQuery, 'i')}, {id: searchId}]}).toArray(function(err, result){
if(err)
return console.log(err);
callback(result.length);
});
}


I am not aware of any other approach, I did try going through concepts like variable hoisting and closures.

Kindly if possible assist me with the correct solutions.

Thanks

Answer

countNumberOfRowsInTweets and countNumberOfRowsInTweetsAfterFilters are asynchronous, which you deal with appropriately by using a callback - however, after calling those functions which populate countWithoutFilters and countTwitter - you use those variables before those asynchronous functions have a chance to complete

the following code should fix that

countNumberOfRowsInTweets(function(countWithoutFilters){
    countNumberOfRowsInTweetsAfterFilters(searchQuery, function(countTwitter){
        queryTweetsCollection(searchQuery, limit, skip, function(data){
            res.send({
                draw: req.query.draw,
                recordsTotal: countTwitter,
                recordsFiltered: countTwitter,
                data: data, 
                page: parseInt(page)
            });
        });
    });
});