Error while saving data in MongoDB atlas with mongoose - node.js

I'm trying to save data in the MongoDB atlas with node.js and mongoose.
Every time I use MySchema.save(), Data is inserting But I'm also getting the error:
UnhandledPromiseRejectionWarning: MongoWriteConcernError: No write concern mode named 'majority;' found in replica set configuration
Also, there is no duplicate entry, Data is also inserting But I'm also getting the error
let User = require('../models/users.models');
const username = req.body.username;
const newUser = new User({username});
newUser.save()
.then(() => res.json('user added!'))
.catch(err => res.status(400).json('Error: ' + err));
User model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
var userSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
trim: true,
minlength: 3
},
},
{
timestamps: true
});
const User = mongoose.model('User', userSchema);
module.exports = User;

I know it was asked 2 months ago, but for those who will encounter the same issue.
You are mistakenly entering a wrong char at the end of the URI string:
mongodb+srv://${ user }:${ password }#track-mkahl.mongodb.net/test?retryWrites=true&w=majority;
You need to delete the ; after the word majority.

This helped me.
const schema = new Schema({ name: String }, {
writeConcern: {
w: 'majority',
j: true,
wtimeout: 1000
}
});
https://mongoosejs.com/docs/guide.html#writeConcern

"mongoURI" : "mongodb+srv://${ user }:${ password }#cluster0.mde0j.mongodb.net/cluster0?retryWrites=true&w=majority "
I get the same error with this in default.json its simple error just delete the &w=majority part at the end and it will be solved

for me it was also in the URI string like #Yossi Saadi has suggested, it's just that I had majoritys written there instead of majority

I think there's something wrong with this line.
let User = require('../models/users.models');
I have created a solution for you.
/models/user.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
mongoose.connect("mongodb://localhost/stack-overflow", { useNewUrlParser: true })
var userSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
trim: true,
minlength: 3
},
},
{
timestamps: true
});
const User = mongoose.model('User', userSchema);
module.exports = User
/routes/userroute.js
const User = require("../models/user")
// Imagine run() as an asynchronous request handler
async function run() {
try {
const user1 = new User({ username: "lidafafnus" })
user1.save((err,result) => {
console.log(err, result)
})
} catch(error) {
console.log(error)
}
}
run()

Related

Getting error while adding record into mongodb using mongoose and Node.js

I am getting the following error while adding some record into mongodb.
Error:
User.create is not a function /--/ "TypeError: User.create is not a
function\n at module.exports.createUsers
Here I am sending some data from postman and my aim is add them into mongodb database. I am explaining my mongo connect file first.
mongo.js:
const mongoose = require('mongoose').Mongoose;
const config = require('../config/settings');
const { MONGO_DB } = require('../config/settings');
const mongooseInstance = new mongoose();
const url = `mongodb://${config.MONGO_USER}:${config.MONGO_PWD}#${config.MONGO_URL}/${MONGO_DB}`;
const options = {
useNewUrlParser: true,
useCreateIndex: true,
connectTimeoutMS: 5000000,
poolSize: 10000,
useUnifiedTopology: true
};
/*
1- Connect to mongo server
*/
mongooseInstance.connect(url, options, (err) => {
if(!err) {
console.log('Mongodb connection successed');
} else {
console.log('Error in DB connection:' + JSON.stringify(err, undefined, true));
}
})
module.exports = mongooseInstance;
The above file used to make connection to my mongodb. I am explaining my code below.
user.js:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const User = new Schema({
name: {type: String},
mobile: { type: String},
email: { type: String},
city: { type: String}
}, {
timestamps: {
CreatedAt: 'CreatedAt',
UpdatedAt: 'UpdatedAt'
},
collection : 'user'
});
module.exports = User;
The above file is my model file. my controller file is given below.
user-controller.js:
const User = require('../models/user');
/*
1- Add user.
*/
module.exports.createUsers = function (req, res,next) {
const data = req.body;
user = User.create(data);
if(!user) {
return res.status(400).json({ success: false, res: []}).end('');
} else {
return res.status(200).json({ success: true, res: user}).end('');
}
}
Here I am trying to create the record but getting the above issue. I need to add record to user collection. Please help me to resolve this issue.
You need to create a model first of your schema.
Simply create it with the following command and export the variable:
const userModel = mongoose.model('user', User);
module.exports = userModel;
In user.js change...
module.exports = User;
to...
module.exports = mongoose.model("User", User)
In your user.js file, you need to update module.exports = User with module.exports = mongoose.model("User", User). Because in Mongoose, models are defined by passing a Schema instance to mongoose.model.
Try to modify your modals' export statement as
const User = module.exports = mongoose.model('User', User);

schema.methods is not a function

I have been trying to create a method on my user schema in mongoose, however it keeps saying method is not a function and I have no idea why. I am fairly new to mongoose and express, and I'm pretty sure I have my files set up currently so I don't know what could be causing this issue. As a last attempt, I tried switching to arrow functions , but that didn't work either.
user routes file
const router = require("express").Router();
let user = require("../models/user_model");
const Joi = require("#hapi/joi");
// GET dreams
// POST dreams
// DELETE dreams
// UPDATE dreams
router.route("/").get((req, res) => {
console.log(user.addType());
res.send("hello this is a users page");
});
user model file
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
username: {
type: String,
required: true,
unique: true,
trim: true,
min: 3
},
password: {
type: String,
trim: true,
required: true,
min: 6
}
},
{
timestamps: true
}
);
userSchema.methods.addTypes = function() {
console.log("woof");
};
userSchema.methods.joiValidate = data => {
let Joi = require("#hapi/joi");
const schema = {
username: Joi.string()
.min(6)
.required(),
password: Joi.string()
.min(6)
.required()
};
return schema.validate(data);
};
module.exports = mongoose.model("User", userSchema);
UPDATE! Other than having typo on your code, you also need to create an instance of your model ('user'). You cannot just call the function of the model.
let user = new user({ // Create an instance first
username: 'Tester',
password: '12345678'
})
console.log(user.addType())
you declared
addTypes()
Cheers

Mongoose findById returns the empty doc

I'm trying to implement CRUD operations using MEAN stack. I'm facing a problem on getting user by Id. It's showing the status true but it returns an empty document.
This is my model:
const userSchema = new mongoose.Schema({
fullName: {
type: String,
required: 'Full name can\'t be empty '
},
userName: {
type: String,
required: 'user name can\'t be empty ',
unique: true
},
email: {
type: String,
required: 'email can\'t be empty ',
unique: true
});
mongoose.model('User', userSchema);
in my controller:
const mongoose = require('mongoose');
const passport = require('passport');
var ObjectId = require('mongoose').Types.ObjectId;
const User = mongoose.model('User');
module.exports.getuser = (req, res, next) => {
if(!ObjectId.isValid(req.params.id))
return res.status(400).send(`No record with given id : ${req.params.id}`);
User.findById(req.params.id, (err, user) => {
if(!err){ res.status(200).json({status: true, user}); }
else{ console.log('Error in retriving User :' + JSON.stringify(err, undefined, 2)); }
});
}
This is the route:
router.get('/:id', jwtHelper.verifyJwtToken, ctrlUser.getuser);
while checking in the postman I'm getting status: true but it returns a blank document.
I'm not getting what's going on anyone please help.
Thanks in advance!!
There could be several reasons why you're not able to find and return a user. I'd go through this checklist to see what might be occurring:
When you define your schema the required field takes a boolean or a function, not a string. To be safe it would make sense to change your strings to true in order to make sure all new db records contain these fields. (https://mongoosejs.com/docs/schematypes.html#schematype-options)
When you import the model in your controller there is no need to call mongoose.model again; this step is performed in your model file. Make sure you're exporting the mongoose.model('User', userSchema) object in the model file/module and then do a normal const User = require(<pathToModelFile>); in the controller module.
If this still doesn't work...
You'll want to make sure your record is in fact saved in your db. Run a mongo shell in terminal by running $ mongo and use commands found here to use your db and search the User collection: https://docs.mongodb.com/manual/reference/mongo-shell/
This is how I would normally code my model and controllers (with routes):
Model file - Note you do need to require Mongoose
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
fullName: {
type: String,
required: true
},
userName: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
});
module.exports = mongoose.model('User', userSchema);
Controller/Router -
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const passport = require('passport');
const User = require('User');
router.get('/:id', jwtHelper.verifyJwtToken, async (req, res) => {
try {
const user = await User.findById(req.params.id);
res.status(200).json({status: true, user});
} catch (e) {
res.status(400).json({err: e});
}
});
module.exports = router;

Mongoose model.save() stuck pending?

I am using mongoose to handle my schemas, with MongoDB, but when trying to save a new entry to a collection the save() method appears to be stuck, neither the then() method or the catch() method of the promise appear to be called.
Does anyone have any ideas?
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');
const config = require('./config');
const UserSchema = new Schema({
email: { type: String, required: true, index: { unique: true } },
name: { type: String, required: false },
password: { type: String, required: true }
});
const User = mongoose.model('User', UserSchema);
console.log('config.database.url', config.database.url);
mongoose.Promise = global.Promise;
return mongoose.createConnection(config.database.url, {
useMongoClient: true
})
.then((connection) => {
const user = new User({
email: 'someuser#somedomain.com',
password: 'xxxxx'
});
const prom = user.save();
// Displays: 'promise: Promise { <pending> }'
console.log('promise:', prom);
return prom
.then((result) => {
// Don't see this output
console.log('result:', result);
})
.catch((error) => {
// Don't see this output either
console.log('error:', error);
});
})
.catch((error) => {
console.log(error);
});
Environment: nodejs 8.9.0, node modules: Mongoose 4.13.6, mongodb 2.2.33
A little more experimenting and it would appear that I need to ensure the model is tied to the connection, such that:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');
const config = require('./config');
const UserSchema = new Schema({
email: { type: String, required: true, index: { unique: true } },
name: { type: String, required: false },
password: { type: String, required: true }
});
let User;
console.log('config.database.url', config.database.url);
mongoose.Promise = global.Promise;
return mongoose.createConnection(config.database.url, {
useMongoClient: true
})
.then((connection) => {
// associate model with connection
User = connection.model('User', UserSchema);
const user = new User({
email: 'someuser#somedomain.com',
password: 'xxxxx'
});
const prom = user.save();
// Displays: 'promise: Promise { <pending> }'
console.log('promise:', prom);
return prom
.then((result) => {
// Don't see this output
console.log('result:', result);
})
.catch((error) => {
// Don't see this output either
console.log('error:', error);
});
})
.catch((error) => {
console.log(error);
});
Alternatively we should use the connect() method that will work with the model associated via mongoose.model.
For createConnection() can be used to create multiple connections, so using a 'global' model is not supported, from what I can tell.
Saying all this it would be nice if save() didn't simply block.
Note: In researching a refinement to my answer I came across the following: Queries hang when using mongoose.createConnection() vs mongoose.connect()

How to automatically create a required field in mongoose

I have a mongoose schema that looks like this:
var userSchema = new Schema({
username: {type: String, required: true, index: {unique: true}},
usernameCanonical: {type: String, required: true, index: {unique: true}}
});
userSchema.pre("save", function () {
this.usernameCanonical = this.username.toLowerCase();
return next();
});
I want to be able to create new users by only entering a username, and let usernameCanonical get generated by the model automatically.
var user = new User({
username: "EXAMPLE_USERNAME"
});
user.save()
When I try to do this I get a validation error from mongoose saying that usernameCanonical is required.
Path `usernameCanonical` is required.
The problem seems to be that the pre-save hooks get called after validation. I don't want to have to manually add a canonical username every time I save a new user. I also don't want to remove the required option from the schema.
Is there some way to get a mongoose model to automatically generate a required field? Adding a default value to the usernameCanonical field in the schema seems to prevent the validation error, but it feels like a hack.
As levi mentioned, you should use the validate() hook:
Save/Validate Hooks
Check this working example based on your code:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
username: {type: String, required: true, index: {unique: true}},
usernameCanonical: {type: String, required: true, index: {unique: true}}
});
userSchema.pre('validate', function () {
if ((this.isNew || this.isModified) && this.username) {
this.usernameCanonical = this.username.toLowerCase();
}
});
const User = mongoose.model('user', userSchema);
mongoose.connect('mongodb://localhost:27017/uniqueTest')
.then(() => {
// create two users
const user1 = new User({
username: 'EXAMPLE_USERNAME-1'
});
const user2 = new User({
username: 'EXAMPLE_USERNAME-2'
});
return Promise.all([
user1.save(),
user2.save()
]);
})
.then(() => {
// update username
return User.findOne({ username: 'EXAMPLE_USERNAME-1' })
.then((user) => {
user.username = 'EXAMPLE_USERNAME_UPDATED-1';
return user.save();
});
})
.then(() => mongoose.connection.close())
.then(() => console.log('script finished successfully'))
.catch((err) => {
console.error(err);
mongoose.connection.close()
.then(() => process.exit(1));
});
I hope this helps.

Resources