How to check if a value exists in mongoose - javascript

Im trying to check if a token is unique before I use the save function, because I cannot create one from within.
I have tried to use the count, find and findOne functions, without any success...
exports.create_client = function(req, res){
token = crypto.randomBytes(8).toString('hex') + '-' + crypto.randomBytes(8).toString('hex') + '-' + crypto.randomBytes(8).toString('hex')
var client = new Client({
first_name: req.body.first_name,
last_name: req.body.last_name,
phone_number: req.body.phone_number,
pin_code: pincode_generator(6),
token: token
});
client.save(function(err, userClient){
if (err){
if(err.errors.phone_number)
res.status(400).send('Phone number is in use.');
if(err.errors.token)
res.status(400).send('Token is in use.');
} else {
res.status(201).send('User created successfully!')
}
});
};
Because of that the token is created in the server side it's the server's responsibility to give a unique token, and to prevent the error.

Before saving your data to Mongodb
you should while defining your schema with mongoose
set unique: true to the fields that you want to be saved as unique
var clientSchema = new Schema({
first_name: String,
last_name: String,
phone_number: {type: String , unique : true }
pin_code: String,
token: {type: String , unique : true }
});
and you should handle errors

So I resolved my issue by making an function object for the save function and call it from within it for saving again when I needed it.

You need to make sure that this value is unique in the DB as shown by rebai previously
client.save((err) => {
if (err) {
if (err.name === "MongoError" && err.code === 11000) {
if (err.keyPattern. phone_number) {
return res.status(422).send({
success: false,
error: "phone_number is already used" });
}
}
return res.status(422).send(err);
}
});

Related

cut user id mongoose response

I'm trying to response from my backend a piece of user id by using lodash, i tryed with id.slice(2, 9) but i get a response without _id. What i'm doing wrong? thanks in advance.
getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else
return res.status(200).json({ status: true, user: _.pick(user, ['_id'.slice(2, 9), 'domain', 'store', 'settings']) });
}
);
},
getUserData: (req, res, next) =>{
User.findById(req.params.userId,
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User record not found.' });
else {
let json = { status: true, user: _.pick(user, ['_id', 'domain', 'store', 'settings']) };
json.user._id = json.user._id.slice(2, 9);
return res.status(200).json(json);
}
}
);
},
Pick the parts you want
Slice the _id to replace it with just the part you want
return the object
Edit:
To cut the ObjectId is necessary first to parse to string, so you need something like this:
var newUserId = user._id.toString().substring(3,user._id.toString().length)
But there is a problem (I think, not tested). If you try to store the cut id into a model object, maybe mongoose don't allow you to add an string (and no valid ObjectId) value instead of ObjectId.
Maybe is neccesary create another object instead of the model with the schema.
Old answer (unrelated) but maybe usefull for somebody:
If you want to hide the result just use select() into your query.
You run a query and then select which fields do you want to get or not into the response.
The proper way to code it is as follows:
query.select({ field1: 1, field2: 1 });
//or
query.select('-field1');
//and many other ways
Docs here

Node/Express session value insert

I'm currently working on a project using Node/Express/MongoDB. I'm using Mongoose to create my schema's and interface with DB. I'm using "express-sessions" module and have a session value set. Specifically, "req.session.user" which equals the username when logged in.
My question here, is how do I go about inserting the session value into mongodb? I have my model defined properly.
doc_type.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TypesSchema = new Schema({
type_id: {
type: String,
uppercase: true,
required: true
},
type_description: {
type: String,
required: true
},
created_by: {
type: String,
required: false
},
creation_date: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('document_types', TypesSchema);
admin.js with routes defined.
adminRouter.route('/doc_types')
.get((req, res) => {
Type.find({}, (err, types) => {
if (err) {
console.error(err)
res.json(err)
}
else if (!req.session.user || !req.session.badge) {
res.redirect('/login');
}
else if (req.session.user || req.session.badge) {
res.render('doc_types', { pageTitle: 'Document Types', types: types, currentUser: req.session.user })
}
})
})
.post((req, res) => {
var type = new Type();
type.type_id = req.body.input_type_id;
type.type_description = req.body.input_type_description;
type.created_by = req.session.user;
type.save((err) => {
if (err) {
console.error(err)
res.json(err)
}
else {
res.json("Success!");
}
})
});
If you look under the .post method, you'll notice the line "type.created_by = req.session.user;". I then save my data into my db via schema. Upon doing so, my session value isn't passed into mongoose scheme. It's empty. However, when I console.log the req.session value, it displays fine there.
Can someone clarify my issue here? I'm stumped. It's probably something stupid I've overlooked.
Welp, it was something stupid. :) I was using postman to "POST" my data to the page. Postman has no idea what the session value was, therefore, no data sent to the mongoose document id. The session was only stored on the server/browser side. Lesson learned, haha.

Existing property return undefined

I started the implementation of a RESTful API usin node.js, express, and mongodb. Everything went well until now, I've a route to authenticate an user as follow:
apiRoutes.post('/authenticate', function(req, res) {
User.findOne({
nickname: req.body.nickname
}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({
success: false,
message: 'Authentication failed. User not found.'
});
} else if (user) {
console.log(user);
console.log(user.nickname);
console.log(user.email);
console.log(user.password);
console.log(user.sexe);
if (user.password != req.body.password) {
res.json({
success: false,
message: 'Authentication failed. Wrong password.'
});
} else {
var token = jwt.sign(user, app.get('salt'), {
expiresInMinutes: 1440 // expires in 24 hours
});
res.json({
success: true,
token: token
});
}
}
});
});
The user is retrieved, and loged in the console as follow:
{ sexe: 'H',
email: 'MrPanda#gmail.com',
password: 'bambou',
nickname: 'MrPanda',
_id: 56cb703e7aef3f83c7dac0a7 }
which is perfect, but then, the three following consol.log return the three following lines:
MrPanda
MrPanda#gmail.com
undefined
H
I see absolutely no reason why the password is undefined at this point, I tried to change the attribute name to 'mdp', same issue... Any ideas ? Thanks
If you are using mongoose it does not return a plain JSON object. It is actually a special mongoose object and may not function how you expect.
You have two options:
Convert the mongoose object to a JSON object.
Add {lean: true} to the Users options parameter.
OR JSON.stringify(user)
OR user.toJSON()
Use the proper get() and set() methods (which you should be doing anyways).
user.get('password')
user.get('email')
user.get('name')
Try that and let me know if it doesn't work still.

Mongoose NodeJS only undefined values [duplicate]

This question already has answers here:
Mongoose always returning an empty array NodeJS
(7 answers)
Closed 7 years ago.
Now I've played with nodeJS and SocketIO and all went fine.
But now I get caught at one query!
// User Auth Event
socket.on('userAuth', function(userObj) {
var queryUserAuth = User.find({
name : userObj.name
})
.where('password',userObj.pword);
queryUserAuth.exec(function(err, userData){
if(err) {
socket.emit('userAuthOK',err);
console.log('!! User: %s or PW not OK', userObj.name);
return handleError(err);
}else {
console.log('User: %s known, userID: %s', userObj.name, userData.userid);
socket.emit('userAuthOK', userData.userid);
socket.join(userData.userid); // Create new room / join this room
}
});
});
But all the time the var "userData" is empty and the console.log above tells me "User: testuser known, userID: undefined".
I can't get this user object from MongoDB this ways, but I can find the user if I take the mongo console.
///////////
EDIT:
After some changes... here the new code... but still without finding the right record and getting a result of null.
// User Auth Event
socket.on('userAuth', function(userObj) {
var queryUserAuth = User.findOne({
name : userObj.name,
password : userObj.pword
});
//.where("password").equals(userObj.pword);
queryUserAuth.exec(function(err, userData){
if(err) {
socket.emit('userAuthOK',err);
console.log('!! User Auth Error: %s', err);
return handleError(err);
}else {
if(!userData){
console.log('!! User: %s or PW not OK.', userObj.name);
socket.emit('userAuthOK','fail');
}else {
console.log('User: %s known, userID: %s', userObj.name, userData);
socket.emit('userAuthOK', userData);
socket.join(userData.userid); // Create new room / join this room
}
}
});
});
Here the output by manual query on mongo shell:
db.user.find({name: 'testuser', password: 'test'}) { "_id" : ObjectId("55a8cc8240fdc97f108d4d11"), "userid" : "1", "name" : "testuser", "email" : "test#test.com", "password" : "test" }
And this is the value of userObj: { name: 'testuser', pword: 'test' }
/////
EDIT2:
here the user.js including the mongoose model of User:
// Load the MongoDB module
var mongoose = require('mongoose');
// user schema
var userSchema = mongoose.Schema({
userid: Number,
name: String,
email: String,
password: String,
status: Number
});
// compiling the user schema
var User = mongoose.model('User', userSchema);
// make this available to our users in our Node applications
module.exports = User;
Here the include of the model:
// Load Mongoose models
var User = require('./models/user');
Try logging userData instead of just userData.userid. It's an Array, not an Object. You want to use .findOne(), not .find().
Also, the syntax for the query methods is:
.where("password").equals(userObj.pword)
Or, you could just add it to your original .findOne():
var queryUserAuth = User.findOne({
name: userObj.name,
password: userObj.pword
});
In addition, your console.log('!! User: %s or PW not OK', userObj.name); doesn't make any sense. Not finding anyone is different than getting an error. You'll want to handle that part as a separate if statement nested within the else block.

How to create an update function on nodejs/mongodb?

Hi I am currently new to nodejs and mongodb what I want to do is make a function to update my win,lose,draw record from my userschema.
My Schema:
UserSchema = new mongoose.Schema({
username:'string',
password:'string',
email:'string',
//Change Made
win:{ type: Number, default: 0 },
lose:{ type: Number, default: 0 },
draw:{ type: Number, default: 0 }
});
My Function for updating:
//Update scores
app.post("/user/updateScores", function (req, res) {
var user = new User({
username:req.body.username,
win:req.body.win,
lose:req.body.lose,
draw:req.body.draw
});
Users.findOne({ username : req.params.username }, function(error, user) {
if (error || !user) {
res.send({ error: error });
} else {
user.update(function (err, user) {
if (err) res.json(err)
req.session.loggedIn = true;
res.redirect('/user/' + user.username);
});
}
});
});
The problem is when I try updating, when I try updating via my html file. It does not update anything and just stays the same (the values win,lose,draw the default value is 0 so when I logout and login again the values of the win,lose,draw record is still zero). I thoroughly checked if the problem was the html and javascript functions that I have made but this is not the case so I think that the problem is the update function I have made. Any of you guys have an idea where I went wrong? Thanks!
Assuming your post is being called correctly from the client, you'll need to be careful about variable and parameter names, as the scope right now is that you're saving an exact duplicate of the user object that was just fetched via findOne.
You had user declared as a variable of the post callback, and then again within the findOne. The inner variable user will take precedence.
app.post("/user/updateScores", function (req, res) {
var username = req.body.username;
Users.findOne({ username : username }, function(error, user) {
if (error || !user) {
res.send({ error: error });
} else {
// update the user object found using findOne
user.win = req.body.win;
user.lose = req.body.lose;
user.draw = req.body.draw;
// now update it in MongoDB
user.update(function (err, user) {
if (err) res.json(err) {
req.session.loggedIn = true;
}
res.redirect('/user/' + user.username);
});
}
});
});

Categories

Resources