Node.js and mongoose (mongodb) error cannot read property '' of null - node.js

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.

Related

NestJS with TypeORM - Catch PostgreSQL unique_violation error on save()

I have got a function in a service that needs to get a value of a new or already existing object from the database and save it.
Issue is that name attribute of this object needs to be unique.
I know i can just create a .some() function over all database objects to check if i can enter this new value but its probably very unoptimal.
I would like to create somethign like this (below) but i have no idea what to do next:
const newObject = await this.repository
.save({
...newObjectDto,
})
.catch(err => {
if (err instanceof QueryFailedError) {
// some code for err checking to make
// sure i only catch the unique_violation
// error and then throw error
}
});
Error code for unique_violation is 23505. You can check out the full list of error codes returned by PostgreSQL here.
In order to catch a unique constraint violation, you can do:
try {
const newObject = await this.repository
.save({
...newObjectDto,
})
}
catch(err) {
if (err instanceof QueryFailedError) {
if(err.code === '23505') {
console.log(`Unique constraint ${err.constraint} failed`);
throw err;
}
}
}

What's the correct syntax to check if cypher query return zero row in javascript

I am trying to determine if a username exists before creating the user. I am using the following code. I need an elegant way to determine if the zero row is returned ...username doesn't exist. for example I know the returned row value would be zero if not found. How can I get access to the row value in the code. Can someone assist...thanks...BTW I am using neo4j3.0 Nodejs with express and Passport
neo4jSession
.run(MATCH (user {email: newUser.email}) RETURN user);
.then (function(result) {
if ((not found) {
.run(CREATE (user: {email:newUser.email, password:newUser.password} ) ASSERT email is UNIQUE RETURN user);
neo4jSession.close();
}) //end of if not found
else (found)
{
// email address already exist
console.log("email address already exist");
neo4jSession.close();
}
}); //end .then
.catch(function(error) {
console.log(error);
});
The Neo4j Driver for JavaScript record module can check if a value from record exists by index or field key using the has method. When evaluating or validating the existence of any field within a record (e.g. determining if a User node contains an existing email address property), using the has instead of the get method can allow for shorter Cypher statements and condensed javascript code; which (IMO) can lead to elegance you are seeking.
Using your original example, you can use a simple Cypher statement to search if a User node contains an email property by passing in a user's input. Utilizing the Neo4j Driver for JavaScript, you can return a result stream with a single record.
Cypher Statement:
MATCH ( u:User { email: $email } )
RETURN u, u.email
If an email address exists as a User node property in the Neo4j database, a stream of records with one field named "u.email" be will returned . The record represents one user found by the statement above. You can access the field value by key using the record module's has method.
Access Record by Field Key:
result.records[0].has('u.email')
The following example is one of many ways you could implement both the simple Cypher statement and has method:
async (_, { email, password }) => {
const session = await driver.session()
const closeSession = await session.close()
const endSession = await driver.close()
let query = 'MATCH (u:User{email: $email}) RETURN u, u.email'
return session
.run(query, { email })
.then(async result => {
closeSession()
let emailExists = result.records[0].has('u.email')
let newUser = result.records[0].get('u').properties
if (
(Array.isArray(result.records) && !result.records.length) ||
(Object.keys(result).length === 0 && result.constructor === Object)
) {
if (!emailExists) {
let query =
'MERGE (u:User { email: $email }) ON CREATE SET u.password = $password RETURN u'
return session
.run(query, { email, password })
.then(result => {
closeSession()
return newUser
})
} else if (Array.isArray(result.records) && result.records.length) {
const emailExists = result.records[0].has('u.email')
if (emailExists) {
closeSession()
throw new Error(emailExists + ' already exists.')
} else {
closeSession()
endSession()
throw new Error('Internal Server Error')
}
} else {
closeSession()
endSession()
throw new Error('Internal Server Error')
}
} else {
closeSession()
endSession()
throw new Error('Internal Server Error')
}
})
.catch(function(err) {
closeSession()
endSession()
if (err) throw err
})
}
Note: This example validates whether a record exists first by evaluating the result with conditional statements, then the e-mail property is checked. A few errors have been handled as well.
Query (use counter):
MATCH (user {email: newUser.email})
RETURN count(user)=1 as user_exists
In javascript:
if ( result.records[0].get('user_exists') !== true ) {
// create new user
}
And, of course, add a unique constraint to the email address for the user.
Though the answer from #stdob is an accepted answer on further research I found out that in case the record do exist, you can't retrieve any data on that query... so:
MATCH (user {email: newUser.email})
RETURN user.name AS Name, count(user)=1 as user_exists
wont yield any data if user exist. The following works:
MATCH (user {email: newUser.email}) RETURN user;
if (!result[0]) {
//no records found
}
else {get user properties}
Thanks to:
https://github.com/mfong/node-neo4j-passport-template/blob/master/models/user.js

Mongoose / Mongodb update return value and error handling

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.

Error "Undefined is not a function " Using callback node.JS

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.

Convert callback to thunk

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.

Resources