Create new subdocument in mongoose - mongodb

What am I missing here? I want to add a sub document to the User schema I already have the schema predefined else where.
User.findById(req.body.id, function(err, user) {
if (err) return console.log(err);
reivews: [{
reviewer: req.body.name,
content: req.body.content
}]
user.save(function(err) {
if (err) console.log(err);
res.send('saved')
})
})
It's saying its saved but I don't see the review in the for the user with the id I tried to save to.
Schema
const Review = new Schema({
reviewer: String,
date : { type: Date, default: Date.now },
content : String,
isLive : { type: Boolean, default: false }
});
const User = new Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
createdAt: { type: Date, default: Date.now },
reviews: [Review]
});
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('Review', Review);
module.exports = mongoose.model('User', User);

Please try this
User.findById(req.body.id, function(err, user) {
if (err) return console.log(err);
if (user.reviews === undefined || user.reviews.length == 0) {
user.reviews = [];
}
user.reviews.push({
reviewer: req.body.name,
content: req.body.content
});
user.save(function(err) {
if (err) console.log(err);
res.send('saved')
})
})
And ensure that data in user as per the defined Schema

Related

How to update a user profile which has a property which is a ref in MongooseJS?

I have a User schema which has reference to a profile schema.
const UserSchema = new Schema(
{
_id: mongoose.Schema.Types.ObjectId,
email: {
....email props...
},
password: {
...password props...
},
profile: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Profile",
}],
},
);
const Profile = new Schema({
_user: {
type: Schema.Types.ObjectId, ref: 'User'
},
'displayName': {
type: String,
default: ''
},
'interestedActivities': ['Ping-pong'], <---- This bad boy/girl is an array
'memberSince': { type: Date, default: Date.now }
}
)
I'd like to create a route which can update the User properties AND the Profile properties in one shot—with a caveat one of the properties on the Profile model is an array!!!
I tried this....
handler
.use(auth)
.put((req, res, next) => {
emailValidator(req, res, next, 'email');
},
async (req, res, next) => {
await connectDB()
const {
profileDisplayName,
profileEmail,
interestedActivities } = req.body;
const update = {
email: profileEmail,
'profile.$.displayName': profileDisplayName,
'profile.$.interestedActivities': interestedActivities
}
const filter = { _id: req.user.id };
const updatedUser = await User.findOneAndUpdate(filter, update, { new: true })
try {
console.log("updatedUser ", updatedUser);
if (updatedUser) {
return res.status(200).send({
updatedUser,
msg: `You have updated your profile, good job!`
});
}
} catch (error) {
errorHandler(error, res)
}
})
export default handler;
My response is:
Status Code: 500 Internal Server Error
Cast to ObjectId failed for value "[
{
id: 'ae925393-0935-45da-93cb-7db509aedf20',
name: 'interestedActivities',
value: []
}
]" (type Array) at path "profile.$"
Does anyone know how I could also afford for the property which is an array?
Thank you in advance!

Mongoose model unique

I´m rather new to this..
If I dont want the user to be able to add duplicated countries to visitedCountry, shoulden unique true work?
Or are there any easy way to block that in the patch?
const User = mongoose.model('User', {
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
accessToken: {
type: String,
default: () => crypto.randomBytes(128).toString('hex')
},
visitedCountries:[ {
country: {
type: Object,
ref: "Country",
unique: true
},
comments: String
}]
})
app.patch('/countries', authenticateUser)
app.patch('/countries', async (req, res) => {
const { username, visitedCountry } = req.body
try {
const countryByAlphaCode = await Country.findOne({ alphaCode: visitedCountry }).lean()
const updatedUser = await User.findOneAndUpdate({ username: username, }, {
$push: {
visitedCountries: { country: countryByAlphaCode, comments: "no comments yet"}
},
}, { new: true })
res.json({ success: true, updatedUser })
} catch (error) {
res.status(400).json({ success: false, message: "Invalid request", error })
}
})
The options unique works for all documents. It prevents two (or more) documents from having the same value for your indexed field. It's often used for the email or username.
For your case, I recommend you to perform a check on the user data before you call findOneAndUpdate.

updating a referenced field in mongodb mongoose

I am trying to "clear" my referenced field in my mongo db.
I am using mongoose, so i have a modelSchema like this.
const usersSchema = new Schema({
userName: { type: String, required: true },
password: { type: String, required: true },
isAdmin: { type: Boolean },
email: { type: String },
profile: {
type: mongoose.Schema.Types.ObjectId,
ref: 'profiles'
}
})
So my question is... if i already have an objectId added in my profile field...
how can i clear that field?
I am receiving from my client an update request with a json like this.
{ userName: 'admin',
password: '123',
email: 'admin#admin.com',
profile: '',
isAdmin: true }
and my controller do this.
usersCtrl.updateUser = (req, res) => {
userModel.findByIdAndUpdate(req.params.id, { $set: req.body }).then(() => {
res.json('updated')
}).catch((err) => {
console.log(err)
res.json(err)
})
}
but i get this error
CastError: Cast to ObjectId failed for value "" at path "profile"
thanks in advance
I could solve my problem, adding this code in my controller
usersCtrl.updateUser = (req, res) => {
if(req.body.profile == ''){
req.body.profile = null
}
userModel.findByIdAndUpdate(req.params.id, { $set: req.body }).then(() => {
res.json('updated')
}).catch((err) => {
console.log(err)
res.json(err)
})
}

User is not a constructor

im getting error: User is not a constructor when trying to add new document to my database. before I used mongoose.model without the Schema method and it worked great but I had to add validator and it needs this syntax and since then I can't make it work
CODE:
var UserSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, index: true, unique: true, required: true },
password: { type: String, required: true }
});
UserSchema.plugin(uniqueValidator);
let User = mongoose.model("user", UserSchema);
module.exports = User;
router.post('/', (req, res) => {
var user = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password
});
// save the user
user.save(function (err) {
if (err) {
console.log('Error in Saving user: ' + err);
throw err;
}
console.log('User Registration succesful');
// return done(null, userData);
res.status(200).send({user: user})
});
});
mongoose.Schema is a constructor, so you need to call it with "new":
var UserSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, index: true, unique: true, required: true },
password: { type: String, required: true }
});
ok I fixed my issue instead of
module.exports = User;
I had to do:
module.exports = {User};

How to do inner reference with mongoose?

I want to do something like following code, but it failed.
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [{
user: { type : Schema.ObjectId, ref : 'User' }
}]
});
var UserModel = mongoose.model('User', User);
Is it able to achieve that purpose?
I think I used the wrong way to check it, actually it works.
Following is my test :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('localhost', 'contacts_test');
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [
{
user: { type: Schema.ObjectId, ref: 'User' }
}
]
});
var UserModel = mongoose.model('User', User);
mongoose.connection.on('open', function () {
var user1 = new UserModel({name: 'kos', phone_number: "003"});
user1.save(function (err) {
if (err) throw err;
var user2 = new UserModel({name: 'java', phone_number: "008"});
user2.contacts = [{user: user1._id}];
user2.save(function (err) {
UserModel.findById(user2._id)
.populate('contacts.user')
.exec(function (err, user) {
if (err) console.error(err.stack || err);
console.log('user name: ' + user.name);
console.error('contact of first result : ', user.contacts[0].user.name);
mongoose.connection.db.dropDatabase(function () {
mongoose.connection.close();
});
});
});
});
});