Mongoose Model is Not Saving, Not Throwing Error - javascript

My mongoose model (node/express app) is neither saving nor throwing an error and I do not know why...
Here is my model. It has a Post referencing many comments by schema ID:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CommentSchema = new Schema({
body: {type: String, required: true, max: 2000},
created: { type: Date, default: Date.now },
flags: {type: Number, default: 0}
}, {
writeConcern: {
w: 0,
j: false,
wtimeout: 200
}
});
var PostSchema = new Schema({
body: {type: String, required: true, max: 2000},
created: { type: Date, default: Date.now },
flags: {type: Number, default: 0},
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
}, {
writeConcern: {
w: 0,
j: false,
wtimeout: 200
}
});
var Post = mongoose.model('Post', PostSchema);
var Comment = mongoose.model('Comment', CommentSchema)
module.exports = {
Post: Post,
Comment: Comment
}
Here is my Route. It simply creates a post from the incoming body and attempts to save it. It references the exported post by model.Post as the exported module is an object.
var express = require('express');
var router = express.Router();
const fs = require('fs');
var model = require('../models/model');
router.post('/uploadPost', (req, res, next)=>{
console.log('inside /uploadPost')
console.log('value of req.files: ', req.files)
console.log('value of req.body: ', req.body)
var post = {
body: req.body.post,
created: Date.now(),
flags: 0,
comments: []
}
console.log('value of post: ', post)
let postInstance = new model.Post(post)
console.log('value of postInstance: ', postInstance)
postInstance.save().then(post=>{
console.log('value of post: ', post)
}).catch( (e) => {
console.log('There was an error', e.message);
});
res.json({return: 'return from /uploadPost'})
})
module.exports = router;
And here is my terminal output. It manages to console.log everything with the exception of either the save callback or the error. I thought it may have been a race condition with the res.json, so I put that in the callback, but that didn't do anything either. What is going on?
value of req.body: { post: 'lkjlkjlk' }
value of post: { body: 'lkjlkjlk',
created: 1552587547653,
flags: 0,
comments: [] }
value of postInstance: { flags: 0,
comments: [],
_id: 5c8a9b1ba7cece70037d3f46,
body: 'lkjlkjlk',
created: 2019-03-14T18:19:07.653Z }
EDIT:
I was connecting to mongoose wrong...sigh.
Here is a correct connection code (the above then is correct):
mongoose.connect("mongodb://localhost:27017/mydb");
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
db.once('open', function() {
// we're connected!
console.log('connected to mongoose db')
});

Related

How to implement mongoose discriminators?

I want to use mongoose discriminator for my project to create a collection of users in which there is a document of owner which I want to implement using discriminators. But I am getting an error of
throw new Error('The 2nd parameter to mongoose.model() should be a ' +
^
Error: The 2nd parameter to mongoose.model() should be a schema or a POJO
at Mongoose.model (D:\Github\Food-Delivery-Website\node_modules\mongoose\lib\index.js:473:11)
at Object. (D:\Github\Food-Delivery-Website\models\Owner.js:21:27)
Code is given below:
// This file is models/User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const options = { discriminatorKey: 'kind' };
const UserSchema = new Schema(
{
userName: {
type: String,
required: true,
unique: true,
},
restOwned: {
// type: [Schema.Types.ObjectId],
type: Number,
},
},
options,
);
module.exports = mongoose.model('User', UserSchema);
Below is the next file
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
const OwnerSchema = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
module.exports = mongoose.model('Owner', OwnerSchema);
Then I import these two files in userController.js
//This file is controllers/userController.js
const User = require('../models/User');
const Owner = require('../models/Owner');
exports.addUser = async (req, res) => {
try {
const newUser = new User({
userName: req.body.userName,
restOwned: req.body.restOwned,
});
const user = await newUser.save();
res.status(201).json({
status: 'Success',
user,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
exports.addOwner = async (req, res) => {
try {
const newOwner = new Owner({
isOwner: req.body.isOwner,
restName: req.body.restName,
});
const owner = await newOwner.save();
res.status(201).json({
status: 'Success',
owner,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
What am I doing wrong here?
enter image description here
The Model.discriminator() method returns a Model.
So you can directly export the discriminator and use it as the model
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
//Directly export the discriminator and use it as the model
module.exports = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
//module.exports = mongoose.model('Owner', OwnerSchema);

Im doing POST method to my API using EXPRESS ROUTER and this does not work

I'm working on API project for client.
The problem is using POSTMAN when i hit POST method the status I get is Status: 500 TypeError.
I tried put some data to my DATABASE manually so that I can check if my CRUD method is working. The GET method is working fine.
This is the API route i created:
const express = require('express')
const Client = require('../../models/Client')
const router = express.Router()
// Get Client
router.get('/', (req, res) => {
Client.find()
.sort({date: -1})
.then(clients => res.json(clients))
.catch(err => res.status(404).json(err))
})
// Create Client
router
.post('/', (req, res) => {
const newClient = new Client({
name: req.body.name,
email: req.body.email,
phone: req.body.phone,
})
newClient
.save()
.then(client => res.json(client))
.catch(err => console.log(err))
})
module.exports = router
This is my Model:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ClientSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
created_at: {
type: Date,
default: Date.now
},
updated_at: {
type: Date,
default: Date.now
},
})
module.exports = Client = mongoose.model("client", ClientSchema);
ERROR Message: Cannot read property 'name' of undefined.
I tried all I can do, changing some code, hard coded some fields, but nothing works.
How to fix the error I get?

How to add elements to req.body?

I am trying to use MongoDB collections and relate one collection to another. I have one collection named "player" and one named "calendar", and I am trying to add player info to calendar events so only the player logged into the system can see their specific events.
I can see all the info of the event when I console log req.body:
{ start_date: '2019-02-09 00:00',
end_date: '2019-02-09 00:05',
text: 'New event',
id: '5c5a6bc5ea427e54cd4714d6',
'!nativeeditor_status': 'updated' }
The id you are seeing is the EVENT id. I want to add a field userID using passport (req.user.id) that way I can then search the collection and populate events of the logged in player.
My question is how to add fields to the req.body element? My calendar and player schemas are as follows:
player.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
calendar: {
type: Schema.Types.ObjectId, ref: 'calendar'
}
});
const User = mongoose.model('player', UserSchema);
module.exports = User;
calendar.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
text: {type: String, required: true},
start_date: {type: Date, required: true},
end_date: {type: Date, required: true},
user: {type: Schema.Types.ObjectId, ref: 'player', required: true}
});
const calendar = mongoose.model('calendar', schema);
module.exports = calendar;
Here is how I'm implementing the calendar in my route index.js:
//schedule
router.get('/calendar', ensureAuthenticated, function(req, res){
req.body.user = req.user.id;
var db = require('mongoskin').db("mongodb://tdipietro87:tdipietro87#tmcluster-shard-00-00-pbtwu.mongodb.net:27017,tmcluster-shard-00-01-pbtwu.mongodb.net:27017,tmcluster-shard-00-02-pbtwu.mongodb.net:27017/test?ssl=true&replicaSet=TMCluster-shard-0&authSource=admin&retryWrites=true", { w: 0});
db.bind('calendar');
var Calendar = require('../models/calendar');
Calendar.find({user: req.user.id}) // query by specific user
.then(function (data) {
// ...
router.use(express.static(path.join(__dirname, 'public')));
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));
router.get('/init', function(req, res){
db.calendar.insert({
text:"My test event A",
start_date: new Date(2018,8,1),
end_date: new Date(2018,8,5)
});
db.calendar.insert({
text:"My test event B",
start_date: new Date(2018,8,19),
end_date: new Date(2018,8,24)
});
db.calendar.insert({
text:"Morning event",
start_date: new Date(2018,8,4,4,0),
end_date: new Date(2018,8,4,14,0)
});
db.calendar.insert({
text:"One more test event",
start_date: new Date(2018,8,3),
end_date: new Date(2018,8,8),
color: "#DD8616"
});
res.send("Test events were added to the database")
});
router.get('/data', function(req, res){
db.calendar.find().toArray(function(err, data){
//set id property for all records
console.log(err);
for (var i = 0; i < data.length; i++)
data[i].id = data[i]._id;
//output response
res.send(data);
});
});
router.post('/data', function(req, res){
console.log(req.body);
console.log(req.user.id);
var data = req.body;
var mode = data["!nativeeditor_status"];
var sid = data.id;
var tid = sid;
delete data.id;
delete data.gr_id;
delete data["!nativeeditor_status"];
function update_response(err, result){
if (err)
mode = "error";
else if (mode == "inserted")
tid = data._id;
res.setHeader("Content-Type","application/json");
res.send({action: mode, sid: sid, tid: tid});
}
if (mode == "updated")
db.calendar.updateById( sid, data, update_response);
else if (mode == "inserted")
db.calendar.insert(data, update_response);
else if (mode == "deleted")
db.calendar.removeById( sid, update_response);
else
res.send("Not supported operation");
});
res.render('calendar', {
name: req.user.name
})
});
});
This is very complicated to answer, but i want to give some clue
const newEvent = new Calendar({ //Calendar is your models name
....fill with another required field in models
text : req.body.text,
user : req.user.id //look again, how you decode incoming token request and declare them
});

Sequelize invalid value Symbol(ne)

I have the following two files running on an Express Node.js server:
home.js
var express = require('express')
var sequelize = require('sequelize')
var db = require('../../shared/db.js')
var op = sequelize.Op
var router = express.Router()
router.get('/home', function(req, res, next) {
db.shared.person.findAll({
where: {
email: {
[op.ne]: null
}
},
order: ['id']
}).then(function (person) {
res.locals = {
person: person
}
res.render('home')
})
})
module.exports = router
db.js
var sequelize = require('sequelize')
var config = {
host: 'localhost',
port: 5432,
username: '...',
password: '...',
database: 'postgres',
dialect: 'postgres',
operatorsAliases: false
}
var db = new sequelize(config)
module.exports = {
shared: {
person: db.define('person', {
id: {
type: sequelize.INTEGER,
primaryKey: true
},
name: sequelize.STRING,
email: sequelize.INTEGER
}, { freezeTableName: true , timestamps: false, schema: 'shared' }),
}
}
When I try to run this query, I get an error claiming Unhandled rejection Error: Invalid value { [Symbol(ne)]: null }
What am I doing wrong? I can use $ne and even ne just fine but they've been deprecated and are not entirely safe to use. Furthermore, it's not just [op.ne] - I get this error when I use any conditional like this.
I'm basing this all on this guide so I'm not really sure what I could be doing wrong here.
Unhandled rejection Error: Invalid value might also appear if you didn't setup string aliases like this:
const Op = Sequelize.Op;
const operatorsAliases = {
$eq: Op.eq,
$ne: Op.ne,
...
$any: Op.any,
$all: Op.all,
$values: Op.values,
$col: Op.col
};
const connection = new Sequelize(db, user, pass, { operatorsAliases });
But, better to remove String based aliases from code and use [Op.ne] for example, Sequlize is planning to deprecate them soon.
Sequelize instance in both db.js and home.js are different, this is because node caches a required module based on it path.
To solve this issue you can pass around correct instance in db.js
module.exports = {
shared: {
person: db.define('person', {
id: {
type: sequelize.INTEGER,
primaryKey: true
},
name: sequelize.STRING,
email: sequelize.INTEGER
}, { freezeTableName: true , timestamps: false, schema: 'shared' }),
},
db: db
}
Then finally use operators from that shared instance to do query
var express = require('express')
var sequelize = require('sequelize')
var db = require('../../shared/db.js')
var op = db.db.Op;
var router = express.Router()
router.get('/home', function(req, res, next) {
db.shared.person.findAll({
where: {
email: {
[op.ne]: null
}
},
order: ['id']
}).then(function (person) {
res.locals = {
person: person
}
res.render('home')
})
})
module.exports = router
One more thing, string operators are completely safe to use if you properly sanitize your user inputs. You only need to use secure operators if you are passing un-sanitized user input to Sequelize methods.
More on this topic
http://docs.sequelizejs.com/manual/tutorial/querying.html#operators-security
https://github.com/sequelize/sequelize/issues/8417

How to call model from inside route?

Not 100% certain if what I want to achieve is the correct way of doing it, so please correct me if I'm wrong.
I'm building a nodejs, express & passport website/app.
In my routes.js, I have the following section:
/* GET Home Page */
router.get('/dashboard', isAuthenticated, function(req, res){
res.render('dashboard', {
user: req.user,
sess: req.session
});
});
After the user is logged in, it displays the 'dashboard'. On that 'dashboard' I'd like to include 10 of their recent logbook entries. I have logbook.js model set up, I'm just unsure how to call it.
My function within models/logbook.js is:
function getLatestEntries(req, res, user){
Logbook.find({ 'uid' : user.uid }, {}, { limit: 10}, function(err, logbook){
return logbook;
});
}
Contents of logbook.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var logbookSchema = new Schema({
id: String,
uid: String,
lid: { type: String, unique: true},
callsign: String,
contact: String,
start: String,
end: String,
band: String,
mode: String,
RSTsent: String,
RSTrec: String,
notes: String
});
var Logbook = mongoose.model('Logbook', logbookSchema);
function getLatestEntries(req, next){
Logbook.find({ 'uid' : sess.uid }, {}, { limit: 10}, function(err, logbook){
if (err){
console.log("Error"+err)
return next(err, null);
}
return next(null, logbook);
});
}
module.exports.getLatestEntries = getLatestEntries;
// make this available to our users in our Node applications
module.exports = Logbook;
In your routes.js:
var Logbook = require('./models/logbook'); // change path if it's wrong
/* GET Home Page */
router.get('/dashboard', isAuthenticated, function(req, res, next) {
Logbook.find({ 'uid' : req.user.uid }, {}, { limit: 10}, function(err, logbook){
if (err) { console.log(err); return next(); }
res.render('dashboard', {
user: req.user,
logbook: logbook
});
});
});
In your models/logbook.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var logbookSchema = new Schema({
id: String,
uid: String,
lid: { type: String, unique: true},
callsign: String,
contact: String,
start: String,
end: String,
band: String,
mode: String,
RSTsent: String,
RSTrec: String,
notes: String
});
var Logbook = mongoose.model('Logbook', logbookSchema);
// make this available to our users in our Node applications
module.exports = Logbook;

Categories

Resources