I am trying to save a new Document (user) in my MongoDb and I use callback. The code runs and goes until save the user, but after that I get an error.So I can save user. I have the following code:
function saveUser(userName, socialMediaType, socialMediaID, setDocNumber, callback){
var user;
if(socialMediaType == "fbUID"){
user = new users({
userName: userName,
userEmail: 'userEmail',
teams:[],
fbUID : socialMediaID
});
}else
if(socialMediaType =="google"){
//do the same
}
var query = {}
query["'"+ socialMediaType +"'" ] = socialMediaID
users.findOne(query, function(err, userFound){
if (err) { // err in query
log.d("Error in query FoundUser", err)
log.d("User Found", userFound)
}else
if(userFound == undefined){ //if user does not exist
user.save(function(err, user){
if(err) return console.error(err);
log.d("user saved", user);
currentSession = sessionOBJ.login(user._id, socialMediaID);
callback(currentSession,"created")
});
}else{
currentSession = sessionOBJ.login(userFound._id, socialMediaID);
callback(currentSession,"logged")
}
});
}
I call the function above through this code:
f(fbUID !== undefined){
userModelOBJ.saveUser(userName,"fbUID", fbUID, function(currentSession, status) {
res.send({"status":status,
"sessionID": currentSession.sessionID,
"expires" : currentSession.date});
});
I am getting this error :
The error is in the line :
callback(currentSession,"created")
What could be the problem?
I already did many researchers but this is a specific case.
Your saveUser() call is missing the setDocNumber argument. It looks like you're not using it in your code though, so you might be able to safely remove it. If you are using it somewhere else (that you haven't shown) then you need to do some argument checking at the top of saveUser() to support optional arguments.
Related
In my user model I have something like this:
register: function(data, next) {
User.findOne({email:data.email}).exec(function findOneUserCB(err, user) {
if (!err && user) {
return next(new Error('Email already exist.'));
}
// other things
});
}
I'm basically trying to return a custom error when the user is found but there isn't any other error from waterline.
But this doesn't work, sails complains that TypeError: Cannot call method 'toString' of undefined.
So I've tried to emulate a waterline error:
//...
var error = {
code: 'E_UNIQUE',
details: 'Invalid',
model: 'user',
invalidAttributes: {
hase: []
},
status: 400
}
return next(error);
//...
This works but it feels very hackish. Isn't it a better way to pass a custom error from within a query callback? I couldn't find any documentation about this topic
You can try something like this
register: function(data, next) {
User.findOne({email:data.email}).exec(function findOneUserCB(err, user) {
if(user){
var alreadyExists = new Error();
alreadyExists.message = require('util').format('User already exists');
alreadyExists.status = 400;
cb(alreadyExists);
}
// other things
});
I am a little confused about the return value of Mongoldb update and how should I handle error with it.
I am using Node.js, Express.js and Mongoose.js as my Mongodb driver
As I look through many tutorial, the only way of error handling I saw is ...
Example: A simple user schema .. and I want to update telephoneNumber
Users
{
email : abc#abc.com,
telephoneNumber : 123456
}
Example of error handling written in node.js that many tutorial taught me
Users.update({email: abc#abc.com}, {'$set': {telephoneNumber : 654321}, function(err, result){
if(err){
//err
}else if(!result){
//update not success
}else{
//update success
}
});
but as I look through Mongodb documentation, I found out that update return WriteConcern value, which return something like this
{
"ok" : 1, // update with no err
"nModified" :1, // successfully update 1 user
"n" : 1 // found 1
}
So my question is, should I handle my error like this instead, so I would know more about the failures of update...
Users.update({email: abc#abc.com}, {'$set': {telephoneNumber : 654321}, function(err, result){
if(err || result.ok === 0){
//err
}else if(result.nModified === 0){
//update fail
}else if(result.n === 0){
//could not be found
}else{
//update success
}
});
Is this a bad approach to update handling in mongoose/mongodb?
Thanks!! :)
Here is how we handle mongoose/mongodb errors. They might be errors like "that value already exists" Or similar issues.
First in the error block of the mongoose call we add:
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err,req,res)
});
}
Which calls a 'getErrorMessage' function which is defined in our errorHandler file, which might call the unique error message function. We also log the errors in our mongo database under a separate collection.
exports.getErrorMessage = function(err,req,res) {
var message = '';
if (err.code) {
switch (err.code) {
case 11000:
case 11001:
message = getUniqueErrorMessage(err);
break;
default:
message = 'Something went wrong. We have logged this issue and will correct';
}
} else {
for (var errName in err.errors) {
if (err.errors[errName].message) message = err.errors[errName].message;
}
}
//log the error to Mongo
ErrorLog.create(err,req,res);
return message;
};
var getUniqueErrorMessage = function(err) {
var output;
try {
var fieldName = err.err.substring(err.err.lastIndexOf('.$') + 2, err.err.lastIndexOf('_1'));
output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists';
} catch (ex) {
output = 'Unique field already exists';
}
return output;
};
Hope that helps, let me know if I can clarify anything.
I am using mongoose with koa.js (maybe a bad choice but had to stick with it).
My initial callback function was :
var _project = yield parse(this);
var userdetails = this.req.user;
var that = this ;
//=============================================================
//FInd a user , check the project name exists under the user, if not then create one
//=============================================================
User.findOne({ '_id': userdetails._id }, function (err, user) {
if (err) {
this.body = "please login again , your session seems to have expired"
} console.log(user.projects.owner.indexOf(_project.name));
if(user.projects.owner.indexOf(_project.name) == -1) { //This means the project is not yet created
var temp_project = new Project(_project);
temp_project.save(function save() {
if(err) {
that.body = "Project coudn't be saved, Please try again sometime later";
} else {
user.projects.owner.push(_project.name);
user.save(function save() {
if (err) {
that.body = "This error is highly unlikely, yet if you see this .Please report this issue";
}
});
that.body = temp_project;
}
});
}
if(user.projects.owner.indexOf(_project.name) >= 0) { //THis means the project exists
that.body = "You have already created a project with same name, please use a different name";
console.log("you reached till here");
}
});
This should have worked in normal express world but later I realised that I need to rewrite in the forms of thunks so my current attemp is
function userfindONE(err, user) {
if (err) {
return "please login again , your session seems to have expired"
}
if(user.projects.owner.indexOf(tproject.name) == -1) { //This means the project is not yet created
var temp_project = new Project(tproject);
temp_project.save(function save() {
if(err) {
return "Project coudn't be saved, Please try again sometime later";
} else {
user.projects.owner.push(tproject.name);
user.save(function save() {
if (err) {
return "This error is highly unlikely, yet if you see this .Please report this issue";
}
});
return temp_project;
}
});
}
if(user.projects.owner.indexOf(tproject.name) >= 0) { //THis means the project exists
return "You have already created a project with same name, please use a different name";
} else return "nothing is matching";
}
function userfindone(userdetails) {
return function(cb) {
User.findOne({ '_id': userdetails._id }, cb);
};
}
var userdetails = this.req.user;
var tproject = yield parse(this);
But this returns the user details from the User.findone from the first mongoose call.
and anything else seems to have ignored. Thanks
this.body = yield userfindone(userdetails)(userfindONE) ;
Take a look at node-thunkify. It should be as simple as wrapping your schema's functions with it.
With Mongoose 3.9.x you can simply yield user.save(), check in your package.json you have installed the unstable release.
Totally new to mongo, I've been checking examples for hours, Trying to check if a user exists in this collection:
{ "name" : "chrispy", "pass" : "xxxx", "_id" : ObjectId("5221b29b69f9e9b11a000001") }
But cannot match name and get the results, i've tried numerous examples, and no luck.
Works well in the console:
mongo main
> db.users.findOne({name : 'chrispy'})
{
"name" : "chrispy",
"pass" : "xxxx",
"_id" : ObjectId("5221b29b69f9e9b11a000001")
}
>
Once I can match the name, I'll match the password. but cant even get as far as matching the user name. Help = 1000 thankyou's!
var name = 'chrispy';
var pass = '';
console.log("About to check for name and pw");
Mongo.connect('mongodb://127.0.0.1:27017/main', function(err, db) {
if(err) throw err;
var collection = db.collection('users');
// does user exist
var doc = collection.findOne({name : name}, function(err,doc){
if(err) throw err;
if(doc)
console.log("1 Found: "+name+", pass="+doc.pass);
else
console.log("1 Not found: "+name);
});
if(doc)
console.log("2 Found: "+name+", pass="+doc.pass);
else
console.log("2 Not found: "+name);
db.close();
});
Console Output:
About to check for name and pw
2 Not found: chrispy
It doesn't even seem to be going in to the findOne() function, external to the findOn() function it fails anyway.
So here are the changes before it started to work, removed var Doc = , and closed the db only after function within findOne() is fired, else it closes the DB before the result.
var name = 'chrispy';
var pass = '';
console.log("About to check for name and pw");
Mongo.connect('mongodb://127.0.0.1:27017/main', function(err, db) {
if(err) throw err;
var collection = db.collection('users');
// does user exist
collection.findOne({name : name}, function(err,doc){
if(err) throw err;
if(doc)
console.log("Found: "+name+", pass="+doc.pass);
else
console.log("Not found: "+name);
db.close();
});
});
Just to be clear, the various database calls are asynchronous actions that utilize Javascript Promises. The call to findOne returns a Promise object, not the found document. That is,
collection.findOne(
{name: name},
function(err,doc) {
/* handle err or process doc */
}
);
is functionally equivalent to
collection.findOne(
{name: name}
).then(
// resolved handler
function(doc) {
// process doc
},
// rejected handler
function(err) {
// handle err
}
);
Your code was starting the asynchronous findOne call and then closing the database before the call has finished (i.e. the promise resolved or rejected). If you need to close the db, you should do it in the callback, once you've obtained your document.
I have a findOne query, and when ever i verify if it returned a empty document i get thrown a error saying 'cannot read property 'username' of null'. That happend when i try to acess doc.username in if(!doc.username) {
My code:
function checkAccDb(username, password) { console.log(2);
/* Check if accounts exists in db */
db.findOne({username: username}, function(err, doc){ console.log(3);
if(err) throw err;
if(!doc.username) {
add2stack(username, password);
}
else if(doc.status == 200) {
end(username, password, 1000);
}
else if(doc.status == 401) {
if(doc.password == password)
end(username, password, 401);
else
add2stack(username, password);
}
else {
add2stack(username, password);
}
});
}
Could anyone please explain me what's happening here?
Thanks!
The query succeeds but doesn't find any matches, so both err and doc are null. You need to check if doc is null and handle that case appropriately.
A typical implementation would be like this
db.findOne({username: username},function(err, doc) {
if (err) {
// handle error
}
if(doc != null)
{
if(!doc.username)
{
//handle case
}
else
{
//handle case
}
}
});
To get the solution check following things.
1. Check model name which you have defined or the name of the folder where all your models are present must be right because in my case in models folder where i have defined all my models i was using different model name so as there was no model named that, thats'y i was getting the error.
2. Check Schema name or folder name where it is located.