1

I want to make an insert in my MongoDB, but it is getting pretty complicated, and it is a simple operation, so I think I am lost at some point.

I have three collections, that I'll simplify for the sake of th question: Sites, Clients, Blacklist.

When a new Client signs up, she instantly gets a Site. Therefore I need to check from the form, if the Client doesn't exist, then if the Client e-mail hasn't been blacklisted, then if the Site doesn't exist, and finally create the elements Client & Site.

I started to do that by callbacks, but it seems overcomplciated for me to do so:

var input = {...}; //assume here I have all the user input
db.collection('Clients').count({'email', input.email}, {limit: 1}, function (err, count) {
    if (count > 0) {
        db.collection('Blacklist').count({'email', input.email}, {limit: 1}, function (err, count) {
            if (count > 0) {
                db.collection('Sites').count({'domain', input.domain}, {limit: 1}, function (err, count) {
                    if (count > 0) {
                        // CREATE THE ACCOUNT
                    } else {
                        res.send("Site already exists.");
                    }
                    db.close();
                });
            } else {
                res.send("Client is blacklisted.");
            }
            db.close();
        });
    } else {
        res.send("Client already exists.");
    }
    db.close();
});

Any other way to achive this kind of operations with ease?

Ideal for me would be something like:

var input = {...}; //assume here I have all the user input
if ( db.collection('Clients').count({'email', input.email}, {limit: 1}) == 0 &&
     db.collection('Blacklist').count({'email', input.email}, {limit: 1}) == 0 &&
     db.collection('Sites').count({'domain', input.domain}, {limit: 1}) == 0 ) {
    // INSERT HERE
} else {
    res.send("Could not insert");
}

2 Answers 2

3

Node programming is very different from sequential programming.

You could use async or another sequential abstraction library like e.g. Seq.

If you don't fear to dive deep you could enable 'Harmony' (and use a cutting edge version of Node.js) and work with Generators and Promises. With this it is possible to write code that looks like sequential code.

But it seems that you are better off using async for now. It takes a little time to get used to it but after a while you read and write the code without much thinking.

And in your special case another way to solve this problem would be to change your database schema completely. Why not having only a Clients and Blacklists collection and move the content of Sites collections directly to the client as embedded documents? Of course this highly depends on your use-cases and cannot generally be regarded as the better solution.

Sign up to request clarification or add additional context in comments.

2 Comments

well, I want it to be async, but, I don't know exactly how to fire those three operations, and then when they are all completed, execute a callback. Maybe, that "async" suggested by Krasu is the way to go. Thanks :)
We both suggested to use async. And @krasu was so smart to give you a solution which hopefully helps you more than my warm words ;-)
1

You could use async. like this:

var input = {...}; //assume here I have all the user input
var validate = function (input, callback) {
    async.parallel({
        clientExists: function(cb) {
            db.collection('Clients').count({'email', input.email}, {limit: 1}, cb)
        },
        blacklisted: function(cb) {
            db.collection('Blacklist').count({'email', input.email}, {limit: 1}, cb)
        },
        siteExists: function(cb) {
            db.collection('Sites').count({'domain', input.domain}, {limit: 1}, cb)
        },
    }, function(error, result) {
        db.close();

        if (error) {
            return callback({
                message: 'Server error', 
                error: error
            });
        }

        if (result.clientExists > 0) {
            return callback({
                message: 'Client already exists',
            });
        }

        if (result.siteExists > 0) {
            return callback({
                message: 'Site already exists',
            });
        }

        if (result.blacklisted > 0) {
            return callback({
                message: 'Client is blacklisted',
            });
        }

        callback(null, true)
    })
}

validate(input, function (error, success) {
    if (error) {
        return res.send(error.message)
    }

    //CREATE ACCOUNT HERE!
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.