Search code examples
javascriptnode.jsmongodbmongooseunique

Javascript MongoDB create another unique id if exists in database


I'm trying to run this function but it's returning undefined.

function generateshortid() {
            const myid = shortid.generate();

            Note.findOne({shortid: myid}, function(err, data) {
                if (data) {
                    const newid = shortid.generate();
                    console.log(data)
                    return newid;
                } else {console.log(myid); return myid;}
            });
        };

Solution

  • It looks like you are returning a value from a callback. This will not work. Why, you ask? Think about this from Mongoose's point of view. When you call Note.findOne(condition, callback), you can imagine Mongoose does something like (note this is over-simplified for sake of argument):

    const result = collection.findOne(condition);
    const note = new Note(result);
    callback(null, note);
    

    It calls the provided callback function and discards the result - the flow control now belongs to your callback. This is a common pattern called continuation-passing style (CPS), and Node.js APIs have used it since the beginning, though most are now transitioning to Promises and async/await, which would have simplified your code.

    Assuming you need to stick to callbacks, you'll need to change the signature of your function to accept a callback, and pass the generated value to it, like so:

            function generateshortid(callback) {
                const myid = shortid.generate();
    
                Note.findOne({shortid: myid}, function(err, data) {
                    if (data) {
                        const newid = shortid.generate();
                        console.log(data)
                        callback(newid);
                    } else {console.log(myid); callback(myid);}
                });
            };
    

    However, there are multiple issues with this function (other than the original inability to get the return value out):

    • Lack of error handling
    • Invalid assumption that the second try will get a unique ID when the first one didn't

    In general, I would recommend learning about callbacks vs. Promises and async/await and reconsidering your unique ID generation strategy. In the end, you may be better served by MongoDB's automatic _id field.