Search code examples
node.jsnode-mongodb-native

While loop to check uniqueness of custom id


I have a MongoDB databse set up with some objects that have a unique code (not the primary key). I should also note that I'm using NodeJS and this code is in my server.js to connect to the MongoDB database.

To generate a new code, I generate one randomly and I want to check if it already exists. If not then we use it no problem, but if it already exists I want to generate another code and check it again. This is the code I use to check if the id already exists:

function createPartyId(callback) {
    var min = 10000, max = 99999;
    var partyId = -1, count = -1;
    async.whilst(
        function () { return count != 0; },
        function (callback) {
            partyId = min + Math.floor(Math.random() * (max - min + 1));
            partyId = 88888;
            getPartyIdCount(partyId, function(num) {
                count = num;
            });
        },
        function (err) {

        }
    );
}

function getPartyIdCount(partyId, callback) {
    count = -1;
    db.db_name.find({id: partyId}, function(err, records) {
        if(err) {
            console.log("There was an error executing the database query.");
            callback(count);
        }
        count = records.length;
        callback(count);
    });
}

Solution

  • (Expanding my comment from above)

    The issue is that createPartyId is an asynchronous function, but you're trying to return the value synchronously. That won't work. Once you touch an async operation, the rest of the call stack has to be async as well.

    You don't include the code that's calling this, but I assume you want it to be something like:

    var partyId = createPartyId();
    // do stuff...
    

    That's not going to work. Try this:

    function createPartyId(callback) {
        var min = 10000, max = 99999;
        var partyId = -1, count = -1;
        async.whilst(
            function () { return (count == 0); },
            function (callback) {
                partyId = min + Math.floor(Math.random() * (max - min + 1));
                partyId = 88888;
                getPartyIdCount(partyId, function(err, num) {
                    if (!err) {
                        count = num;
                    }
                    callback(err);
                });
            },
            function (err) {
              // this is called when the loop ends, error or not
              // Invoke outer callback to return the result
              callback(err, count); 
            }
        );
    }
    
    function getPartyIdCount(partyId, callback) {
        count = -1;
        db.db_name.find({id: partyId}, function(err, records) {
            if(err) {
                console.log("There was an error executing the database query.");
                callback(err);
            }
            count = records.length;
            callback(null, count);
        });
    }
    

    (I've also adopted the default node.js convention of always returning errors as the first argument to callback functions.)

    So, to use this you would do:

    getPartyId(function (err, num) {
        if (err) { return aughItFellOver(err); }
    
        // do stuff
    });