Express/Mongoose REST trouble - javascript

Im running Express on my application with a delete route below:
router.route('/lists/:id')
.delete(function(req, res){
Entry.remove({
_id: req.params.id
}, function(err, list){
if(err)
res.send(err)
list.title = req.body.title;
res.json({message: 'successfully deleted'});
console.log('DELETE on /lists/'+ req.params.id);
});
});
Here is my Mongoose schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ListSchema = new Schema({
title: String
});
module.exports = mongoose.model('List', ListSchema);
When my application hits the delete route, my terminal logs the appropriate statement, but the model is not deleted from the database. When I call fetch on the collection, all of there records are still there.
I am using a very similar approach on a different collection of data on my website, and it works fine, so Im really at a loss for why this is happening.

Mongoose assigns each of your schemas an _id field by default if one is not passed into the Schema constructor. The type assiged is an ObjectId to coincide with MongoDBs default behavior
Try passing the _id as ObjectId:
var ObjectId = require('mongoose').Types.ObjectId;
var query = { _id: new ObjectId(req.params.id) };

Related

Accessing user information in Express JS is returning Undefined

I am currently using Passport for authentication within my application. When trying to pull a users email in order to store in my db along with other information, I get a returned value of undefined. If I pull the entire user object I get the correct information though. See below.
Here is the server.js file initializing the session.
app.use(session({
secret: 'sessionSecret'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
Here is the route information
app.get('/itemCreation', function (req, res) {
res.render('itemCreation.ejs', {
user: req.user
});
});
app.post('/itemCreation', function (req, res) {
var item = new itemSchema();
item.local.productName = req.body.productName;
item.local.itemPrice = req.body.itemPrice;
item.local.Quantity = req.body.Quantity;
item.local.Description = req.body.Description;
console.log(req.user.firstName);
item.save(function (err) {
if (err)
throw err;
else
console.log('Saved item information successfully');
});
res.redirect('/shop');
});
Here is my Item model
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var itemSchema = mongoose.Schema({
local : {
productName : String,
itemPrice : Number,
Quantity : Number,
Description : String
}
});
module.exports = mongoose.model('item', itemSchema);
Here is the result of pulling the whole object, which I get by calling
console.log(req.user);
and here is the result of pulling just the email from the object, which I get by calling
console.log(req.user.email);
It shoud be console.log(req.user.local.email);

Setting own mongoose schema _id property

I've found a number of examples showing the ability to set your own _id property to something other than the default ObjectId in a mongoose schema:
var personSchema = new mongoose.Schema({
_id: Number,
name: String
});
A few questions I have:
1) Does this auto increment and handle everything else for me? The only examples I've seen don't show any additional code to ensure this a unique and incremented key in MongoDB.
2) This doesn't seem work for me. When I remove the _id from the schema, I get documents posting correctly as expected, but when I add it (_id: Number), nothing gets added to the collection, and Postman returns just an empty object {}. Here's the relevant code:
var personSchema = new mongoose.Schema({
_id: Number,
name: String
});
var Person = mongoose.model("Person", personSchema);
app.get("/person", function (req, res) {
Person.find(function (err, people) {
if (err) {
res.send(err);
} else {
res.send(people)
}
});
});
app.post("/person", function(req, res) {
var newPerson = new Person(req.body);
newPerson.save(function(err) {
if (err) {
res.send(err);
} else {
res.send(newPerson);
}
});
});
A POST request returns {}, and neither the collection nor document are created.
If you include an _id field in your schema definition, when you insert a document you must supply it with your own manually generated _id. If you don't, the document will not get inserted.
Alternatively, if you do not include an _id field in your schema definition, Mongoose will create this for you automatically, when the document is inserted, and it will be of type ObjectId (which is the default way that MongoDB sets the _id field on documents).

Dynamic mongoose schema parsing with ExpressJS

I am working on a ExpressJS and MongoDB project that involves parsing dynamic mongoose schema. The way I set up the dynamic schema is and parse it :
Step-1
//Creating a mongoose schema
var userSchema = mongoose.Schema({
measurements : [
mongoose.Schema({
time: String
})
]});
Step-2
//Creating a mongoose model for the schema
var User = mongoose.model('User', userSchema);
var user = new User();
user.measurements = [{time:req.body.time}]
//save the info
user.save(function(err) {
if (err)
res.send(err);
res.send({message: "User Info created"});
});
});
Expected result :
A example with JSON validator to explain my goal clearly:
But the issue is my code posts data in the following way to the mongo database :
I was wondering if it is possible to post new array object with time attribute instead of having the comma separated values.
Any thoughts and suggestions on this would be appreciated.
Thanks
You are doing it the wrong way.
Try this:
var user = new User();
user.measurements.push({time:req.body.time});
//save the info
user.save(function(err) {
if (err)
res.send(err);
res.send({message: "User Info created"});
});
});

How to do unit test in dependent modules (node.js)?

I have an application with two modules (Book and User). The book model looks like this:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var BookModel = new Schema({
name: String,
author: String,
description: String,
_user: {type: Schema.Types.ObjectId, ref: 'User'}
});
module.exports = mongoose.model('Book', bookModel);
And the user model:
var mongoose = require('mongoose'),
bcrypt = require('bcryptjs'),
Schema = mongoose.Schema;
var userModel = new Schema({
name: String,
username: String,
password: String,
});
module.exports = mongoose.model('User', userModel);
I want to do a unit test in the POST method (inserting a book in the DB) with the condition of not allowing empty name. This is what I have in the POST method:
var post = function (req, res) {
var bookNew = new book(req.body);
// get paylod from the user's token
var payload = tokenManager.getPayload(req.headers);
if (req.body._user)
delete req.body._user;
if (!req.body.name) {
res.status(400);
res.send("Name is required");
} else if (payload == null || payload == undefined) {
res.status(400);
res.send("Token error");
} else {
// store the user id
bookNew.set('_user', payload.id);
bookNew.save();
res.status(201);
res.send("Book saved");
}
};
As you can see, I get the payload from the token (created when the user is logged in). I do this because the payload contains the user id and, then, I insert it in _user (property in book model).
The problem is that if I do a unit test in order to verify if the book’s property (name) is filled, I don’t have a user to retrieve the payload. Therefore, the payload will be undefined and the book unit test will not be successful in any case. Do you have any suggestion on what I should do? It looks like I have to create a user in order to test all book modules… but I am not sure if that is the most suitable solution.

Multiple connection error when using node js and mongodb

I'm using the following schema located in my /routes/schema.js file...
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
username: String,
password: String,
name: String,
last: String,
year: Number,
degree: String
});
var User = mongoose.model('User', userSchema);
module.exports = {
User: User
}
In my /routes/register.js file I am storing some information using POST data...
var User = require('../routes/schema').User;
exports.postRegister = function (req, res) {
var u = new User({
username: req.body.reg_username,
password: req.body.reg_password,
name: req.body.reg_name,
last: req.body.reg_lastname,
year: req.body.reg_year,
degree: req.body.reg_degree
});
u.save(function (err) {
if (err) {
throw err;
}
else {
console.log("saved");
res.render('index', { title: 'Express' });
}
});
}
Everything gets saved fine in my Database. But now, this register.js file redirects the user back to /routes/index.js where the user must then sign in using some credentials stored in the database.
So in my index.js file I need to check if username and password exist together in a collection in my database, I tried the following...
var User = require('../routes/schema').User;
exports.signin = function (req, res) {
User.findOne({
username: req.body.log_username,
password: req.body.log_password
}, function (err, docs) {
if (docs.length) {
console.log("name exists");
}
else {
console.log("no exist");
}
});
};
I used the findOne function with the same Schema to check if username and password exist in a collection in the database, but it doesn't work properly. I seem to get a multiple connection error and I do not know how to avoid it.
When I try to login using some credentials already in the database, the console prints out no exist meaning the else statement in exports.signin is reached.
The value of the docs will be null if the object is not found in the collection.
If the user enters wrong credentials, you will be calling docs.length on null object, which will cause an error. Use docs != null instead, to avoid calling length on null object.
try it docs.length !== 0 this is check docs field is existed or empty.

Categories