Node and mongoose - Acces object inside another object - javascript

I got this schema:
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
email: {type:String, unique: true, lowercase: true},
cpf: String,
password: String,
profile:{
name:{type:String, default:''},
photo: {type:String, default:''}
},
adress:String,
history:[{
date: Date,
paid:{type:Number, default:0},
item:{type:mongoose.Schema.Types.ObjectId, ref:'Products'}
}]
});
module.exports = mongoose.model('User', userSchema);
But, when I use User.create({email:req.body.email, password:req.body.password, profile.name: req.body.name}), when I try to pass some value to profile.name, console gives me an error. SyntaxError: Unexpected token .
How can I acess this object and pass some value for him?

Javascript lets you omit the quotes around keys on objects if your key contains a limited set of characters. The period . isn't one of them so you need to quote your key.
User.create({
email: req.body.email,
password: req.body.password,
'profile.name': req.body.name
})

Related

How can i reference another mongoose model for people who like a certain post?

I am currently trying to track which users like a certain post and based on that information there will be a 'liked' functionality on the post if the user already liked it. How would I go about this with these two current mongoose Schemas that I have?
User.js
const mongoose = require('mongoose')
const userSchema = mongoose.Schema({
username: String,
name: String,
email: String,
passwordHash: String,
dateOfBirth: Date,
location: String,
addictions: Array,
groups: Array,
biography: String,
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
],
profileImageURL: String,
following: Number,
followers: Number
})
userSchema.set('toJSON', {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString()
delete returnedObject.__v
// the passwordHash should not be revealed
delete returnedObject.passwordHash
}
})
const User = mongoose.model('User', userSchema)
module.exports = User
post.js
const mongoose = require('mongoose')
const postSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
images: Array,
video: String,
gif: String,
date: Date,
tags: String,
likes: Number,
comments: Number,
shares: Number,
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String,
replies: {
type: mongoose.Schema.Types.ObjectId,
ref: "Replies"
},
})
const Post = mongoose.model('Post', postSchema)
module.exports = Post
Should i make a separate schema for likes to achieve this or can it be done with the two schemas i already have defined? Thanks!

Mongoose Remove key(s) from child schema (nested subdocuments)

I have two schemas defined, imageSchema and userSchema. imageSchema has key postedBy: userSchema. Question is shall I remove unused attributes of userSchema (like password) when nested into imageSchema, if so how to do it?
var userSchema = new mongoose.Schema({
email: String,
password: String,
name: String,
}, {versionKey: false})
var imageSchema = new mongoose.Schema({
filePath: String,
user: userSchema,
createdAt: Date,
comments: [{body: "String", by: mongoose.Schema.Types.ObjectId}]
})
...
app.post("/upload-image", async function(req, res){
if(req.session.user_id) {
...
fileSystem.rename(oldPath, newPath, function(err2){
getUser(req.session.user_id, function(user){
delete user.password
var currentTime = new Date().getTime()
Image.create({
"filePath": newPath,
"user": user,
"createdAt": currentTime,
"comments": []
}, function(err2, data){
res.redirect("/?message=image_uploaded")
})
...
So after I created a new document of Image, I checked the database, the user field of the new Image has the attribute of password, which is not desired. "delete user.password" seems not working. How should I delete this attribute? Shall I do it when defining the imageSchema, or remove it when posting the data (the app.post part)?
This can be done is multiple ways. The way i like is to exclude the field from schema and also exclude while insertion.
Exclude from schema
var imageSchema = new mongoose.Schema({
filePath: String,
user: userSchema.pick(["email", "name"]), // this will return schema with only email and name from the schema
createdAt: Date,
comments: [{body: "String", by: mongoose.Schema.Types.ObjectId}]
})
Exclude while inserting
we are omitting the user here before insertion
this can be also done with underscore/lodash _.omit(user, 'password')
getUser(req.session.user_id, function({password, ...user}){
Image.create({
"filePath": newPath,
"user": user,
"createdAt": Date.now(),
"comments": []
})
}

Cast to ObjectId failed for value error in Mongoose findOne

I've been struggling with a weird exception and still confused about it after an hour.
CastError: Cast to ObjectId failed for value "pedrammarandi#gmail.com"
at path "_id" for model "Account"
I'm trying to retrieve an Account via email address. Here is my query
export async function getPendingRecipients(user_id, email_address) {
const account = await Account
.find({email: email_address})
.exec();
return true;
}
This is my Schema object
const userGmailSchema = new Schema({
id: {
type: String,
unique: true
},
displayName: String,
image: Object,
accessToken: String,
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
refreshToken: {
type: String,
default: null
},
email: {
type: String,
unique: true
},
emails: [
{
type: Schema.Types.ObjectId,
ref: 'Emails'
}
]
});
I'm not sure, but I guess the problem is you wrote an id field.
In MongoDB, the "primary key" is _id field, which is an ObjectId object (actually it's a 12-byte-value), and in mongoose, id is a virtual getter of _id, easily said, id is an alias of _id.
(A little different is that, _id returns ObjectId, id returns String version of _id.)
By default, mongoose manage _id field automatically, so commonly we should not write anything about id in schema.
If your id is for something like primary key ID in SQL DB, just remove it from mongoose schema. If it's means something else in your app, try to add an option:
const userGmailSchema = new Schema({
// your schemas here
},
{
{ id: false } // disable the virtual getter
})
or rename it.
http://mongoosejs.com/docs/guide.html#id
Hope this helps.

Querying from [array of objects] with mongoose find

I have two Mongo schemas defined as follows:
var userSchema = new mongoose.Schema({
email: String,
password: String, //hash created from password
firstName: String,
lastName: String,
comment:{userComment:String,adminComment:String},
postalAddress: String,
city: String,
state: String,
country: String,
institution: String,
privilege: {type: String, enum:['normal','chair','admin']},
status: {type:String, enum: ['granted','removed','pending']},
myConference:[{type:Schema.Types.ObjectId,ref:'Conference'}],
mySubmission:[{type:Schema.Types.ObjectId,ref:'Submission'}]
});
var conferenceSchema = new mongoose.Schema({
conferenceTitle: {type:String},
conferenceDescription: String,
conferenceStartDate:{type:Date, default: Date.now},
submissionEndDate:{type:Date},
reviewEndDate:{type:Date},
**conferenceMembers:[{type:Schema.Types.ObjectId,ref:'User'}]**,
conferenceSubmissions:[{type:Schema.Types.ObjectId,ref:'Submission'}],
createdBy:{type:Schema.Types.ObjectId,ref:'User'},
//chairMembers:[{type:Schema.Types.ObjectId,ref:'User'}],
department:String
});
Requirement: I want to fetch all the Conference objects which match a certain _id i.e. unique for each 'User' schema object.
conferenceMembers is an array of 'User' objects
What I did:
It's a POST:
var userId=req.body.userId
**Conference.find({userId: {$in: [Conference.conferenceMembers]}},function(err,conf){**
if(err){
return res.send(500, err);
}
return res.send(200,conf);
But, the filter doesn't seem to work here, I tried with $elemMatch as well but no luck.
To fetch all the documents which has specific userId in conferenceMembers, you can do this:
Conference.find({conferenceMembers : userId}).exec(function(err,conf){...});
if you want to populate the users too you can use mongoose populate.
Conference.find({conferenceMembers : userId}).populate('conferenceMembers').exec(function(err,conf){...});

Difference between saved/load json object in Mongoose

I have a problem saving a json object in mongodb(Mongoose) so when i make the insert everything is ok, but when i make the request of the same object, Mongoose return a modified json. Its like Mongoose autocomplete the twitter field and i dont know why.
Here is my code:
UserSchema = mongoose.Schema({
firstName: String,
lastName: String,
email: String,
salt: String,
hash: String,
twitter:{
id: String,
email: String,
name: String
},
facebook:{
id: String,
email: String,
name: String,
username: String,
photo: String,
gender: String
}
});
I save json in my database:
User.create({
email : profile.emails[0].value,
facebook : {
id: profile.id,
email: profile.emails[0].value,
name: profile.displayName,
username: profile.username,
photo: profile.photos[0].value,
gender: profile.gender
}
}, function(err, user){
if(err) throw err;
// if (err) return done(err);
done(null, user);
});
But i when mongoose return a json.
Mongoose generated a field in the json. twitter:{} <----
I dont know why, can anyone lend me a hand?
If you look at the document saved to the MongoDB, you'll see that the twitter object isn't actually present unless the properties of the sub object are set. The object is created so that you can conveniently set properties without needing to worry about creating the sub/nested object. So you can do this:
var user = new User();
user.twitter.id = 'wiredprairie';
user.save();
Results:
{ "_id" : ObjectId("522259394eb9ed0c30000002"),
"twitter" : { "id" : "wiredprairie" }, "__v" : 0 }
And if you went one step further and wanted a more "pure" view of the data, you could use toJSON on the Mongoose model instance:
console.log(user.toJSON());
results:
{ _id: 522259ad3621834411000001, twitter: { id: 'wiredprairie' } }

Categories

Resources