Reputation: 1373
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
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
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