0

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

Vipul Mehra
  • 141
  • 1
  • 2
  • 8

2 Answers2

0

It's because javascript is asynchronous

this codes execute first

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

before filling your count variables which are

countWithoutFilters = data;
countTwitter = data;
Beginner
  • 4,118
  • 3
  • 17
  • 26
0

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)
            });
        });
    });
});
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • This works. Thank you so much Jaromanda. Could you also provide me with the resources to understand this in much details? Thanks again. – Vipul Mehra Oct 24 '16 at 02:55
  • the question this question is marked a duplicate of should be a starting point - http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Jaromanda X Oct 24 '16 at 02:57
  • Thank you so much Jaromanda. I will go through this. – Vipul Mehra Oct 24 '16 at 02:59