Darkrum
Darkrum

Reputation: 1373

Node.js mongodb trouble with callbacks

So I'm trying to create a sign up route that checks to see if the user exists first and i have the database call in a separate function that needs to return true or false when it's done. The problem is i'm not very familiar with callbacks and the whole asynchronous thing everything that i have searched for does not seem to work keeps giving me.

TypeError: callback is not a function

This is my code any help or direction would be appreciated.

function pullUserFromDatabase(username, callback) {



console.log(username); //for debug
    mongodb.connect(url, function(err, db) {
        if(err) {
                console.log("didn't get far" + err) //for debug

            }

        var collection = db.collection(username);

        collection.findOne({username}, function(err, item) {
            if(err) {
                console.log("nope it broke" + err) //for debug

            } else {
                console.log("it worked" + JSON.stringify(item)) //for debug
                callback(true);
            }
        });




});

}

app.post("/signup", function(req, res) {
    var username = req.headers["username"],
        password = req.headers["password"],
        randomSalt = crypto.randomBytes(32).toString("hex"),
        passwordHashOutput = crypto.createHash('sha256').update(password + randomSalt).digest("hex");

        if(!username || !password) {
            res.send("Username or password not provided.")
        } else if(pullUserFromDatabase(username)) {
            res.send("User exist.")
        }
});

Upvotes: 1

Views: 929

Answers (2)

Jared Dykstra
Jared Dykstra

Reputation: 3626

The reason that callback is undefined is because you didn't pass a 2nd argument to pullUserFromDatabase(username) Provide a 2nd argument, eg. pullUserFromDatabase(username, function(result) {/* do something here with the result variable */})

If you're not very familiar with aync & callbacks, you might find it more intuitive to use promises, but that comes with its own learning curve.

In the context of the original code, this looks like:

    ...
    if(!username || !password) {
        res.send("Username or password not provided.");
        return;
    } 

    pullUserFromDatabase(username, function(result) {
        if(result) {
           res.send("User exist.");
        } else { 
           // TODO: Handle this case.  If res.send() is never called, the HTTP request won't complete
        }
    });
    ...

Also, you need to ensure your callback is always invoked. Add callback(false):

   console.log("nope it broke" + err); //for debug
   callback(false);

Do a similar step after "didn't get far" and then return so the callback doesn't get invoked multiple times.

Upvotes: 0

chridam
chridam

Reputation: 103365

You need to use the callback as follows:

function pullUserFromDatabase(data, callback) { 
    console.log(data.username); //for debug
    mongodb.connect(url, function(err, db) {
        if(err) {
            console.log("didn't get far" + err) //for debug
        }

        var collection = db.collection(data.collection);
        collection.find({"username": data.username}).count(function (err, count) {
            callback(err, !! count);
        });
    });
};




app.post("/signup", function(req, res) {
    var username = req.headers["username"],
        password = req.headers["password"],
        randomSalt = crypto.randomBytes(32).toString("hex"),
        passwordHashOutput = crypto.createHash('sha256').update(password + randomSalt).digest("hex");

        if(!username || !password) {
            res.send("Username or password not provided.")
        } 

        var data = {
            username: username,
            collection: "collectionName"            
        }

        if(!username || !password) {
            res.send("Username or password not provided.")
        }

        pullUserFromDatabase(data, function(err, exists) {
            if (err) {
                res.send(400, "Error - " + err);
            }
            else if(exists) {
                res.send(200, "User exists.");
            }
            res.send(200, "User does not exist.");
        });
});

Upvotes: 1

Related Questions