Cannot read the property of id undefined - javascript

I'm making a website where you can share campground photos. And when someone makes a comments I want only comment's owner to see delete and edit options.
I've made an model for comment and made an author object that includes comment's owner's id and username. But when I try to get the owner's ID from that author object it returns undefined also if I try to get data by find method and write Comment.author.id it returns syntax error and says Unexpected token "."
That's my comment model.
var commentSchema = new mongoose.Schema({
text: String,
author:{
username: String,
id: String,
}
});
That's the campground route
Campground.findById(req.params.id).populate("comments").exec(function(err, foundCampground){
if(err){
console.log(err);
}else{
//render show template with that campground
console.log(foundCampground.comments);
User.findById(req.user._id, (err, user)=>{
if(err){
console.log(err);
}else{
console.log(foundCampground.comments._id);
Comments.find({Comments.author.id: foundCampground.comments._id}, function(err, comment){
var authID = foundCampground.author.id;
var userID = user._id;
var commentID = comment.author.id;
console.log("Comment Id " + commentID);
console.log("UserID "+userID);
res.render("campgrounds/show",{campground: foundCampground, authID: authID, userID: userID});
});
}
});
}
});
Same thing worked for the campground model
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}],
author: {
id: String,
user: String,
}
});
I expect to get the user id from comment.author.id but I get undefined.

You may need to replace Comments.find({Comments.author.id: foundCampground.comments._id} with Comments.find({"author.id": foundCampground.comments._id}.

Related

mongoose : insert data into an array of nested objects

I am working on a project using node.js mongodb. My schema somewhat looks like:
var Doctor = new Schema({
email : String,
password : String,
Dname : String,
blockAppoint:[{
day:String,
sslot:[Number],
eslot:[Number],
address:String,
status1:String
}]
});
If I take all these values as input from user, I can't figure out how to insert into the array of nested objects.
If my post api looks like:
var doc = new Doctor({
email : req.body.email,
password : req.body.password,
name : req.body.Dname,
blockAppoint:{
status1:req.body.xx,
day:req.body.day,
sslot:req.body.sslot,
eslot:req.body.eslot,
address:req.body.address
}
});
doc.save(function(err){
if(err){
res.send(err);
return;
}
res.json({
success: true,
message: 'doctor has been added!'
});
});
I'm able to input just one entry into the database. Does anyone know how do I change my api code so as to be able to take read input into my database.
Try adding the values to an array first using the push() method:
var sslot = [], eslot = [], blockAppoint = [];
sslot.push(req.body.sslot);
eslot.push(req.body.eslot);
blockAppoint.push({
status1: req.body.xx,
day: req.body.day,
sslot: sslot,
eslot: eslot,
address: req.body.address
});
var doc = new Doctor({
email: req.body.email,
password: req.body.password,
name: req.body.Dname,
blockAppoint: blockAppoint
});

Mongoose populate documents

I got 3 database models in mongoose that looks like this:
//profile.js
var ProfileSchema = new Schema({
username: { type: String, required: true },
password: { type: String, required: true },
matches: [{ type: Schema.Types.ObjectId, ref: 'Match' }]
});
//match.js
var MatchSchema = new Schema({
scores: [{ type: Schema.Types.ObjectId, ref: 'Score', required: true }],
});
//score.js
var ScoreSchema = new Schema({
score: {type: Number, required: true},
achivement: [{type: String, required: true}],
});
And I try to populate a profile with
Profile.findOne({ _id: mongoose.Types.ObjectId(profile_id) })
.populate('matches')
.populate('matches.scores')
.exec(function(err, profile) {
if (err) {...}
if (profile) {
console.log(profile);
}
});
The matches get populated but I dont get the scores in matches to populate. Is this not supported in mongoose or do I do something wrong? Populate gives me this:
{
user_token: "539b07397c045fc00efc8b84"
username: "username002"
sex: 0
country: "SE"
friends: []
-matches: [
-{
__v: 1
_id: "539eddf9eac17bb8185b950c"
-scores: [
"539ee1c876f274701e17c068"
"539ee1c876f274701e17c069"
"539ee1c876f274701e17c06a"
]
}
]
}
But I want to populate the score array in the match array. Can I do this?
Yes, you are right. I tried using Chaining of populate I got same output.
For your query please use async.js and then populate by the method mentioned below.
For more details please have a look at this code snippet. It is a working, tested, sample code according to your query. Please go through the commented code for better understanding in the code below and the link of the snippet provided.
//Find the profile and populate all matches related to that profile
Profile.findOne({
_id: mongoose.Types.ObjectId(profile_id)
})
.populate('matches')
.exec(function(err, profile) {
if (err) throw err;
//We got the profile and populated matches in Array Form
if (profile) {
// Now there are multiple Matches
// We want to fetch score of each Match
// for that particular profile
// For each match related to that profile
async.forEach(profile.matches, function(match) {
console.log(match, 'match')
// For each match related to that profile
// Populate score achieved by that person
Match.find({
_id:match.id
})
.populate('scores', 'score')
.exec(function (err, score) {
if (err) throw err;
// here is score of all the matches
// played by the person whose profile id
// is passed
console.log(score);
})
})
}
});
Profile.findOne({ _id: mongoose.Types.ObjectId(profile_id) })
.populate('matches.scores')
.exec(function(err, profile) {
if (err) {...}
if (profile) {
console.log(profile);
}
});

Update/Put error save in Express and Mongoose

I am beginner in Express. I have the following code in my router/controller for update a model. In one hand I don't want to modify the date of "create_date" parameter, and on the second hand this code returns me a error.
updateFood = function(req, res){
Food.findById(req.params.id, function(err, food){
food.food_name = req.body.food_name;
food.description = req.body.description;
food.image = req.body.image;
food.create_date = Date.now();
food.category = req.body.category;
Food.save(function(err){
if (!err){
console.log("updated!");
} else {
console.log(err);
}
});
res.send(food);
});
};
Here is my schema:
var food = new Schema({
food_name: {type: String, unique: true},
description: String,
image: String,
create_date: {type: Date, default: Date.now()},
category: {
type: String,
cats: ['Meat', 'Fish', 'Vegetables']
}
});
module.exports = mongoose.model('Food', food);
When I try to update a food with Postman with PUT. The console returns me the following response:
Food.save(function(err){
^
TypeError: Object function model(doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
} has no method 'save'
What can I do? Anyone knows where is my mistake? Thanks.
I believe you meant food.save(..); instead of Food.save(..);, but if all you're doing is updating the model, you could use findByIdAndUpdate() instead.

using populate to display username instead of id

I'm running Expressjs with mongoosejs I made the connection between the collections CustomerId as below:
.
.
/**
* Customer Schema
*/
var CustomerSchema = new Schema({
id : Number,
name: String,
joined: { type: Date, default: Date.now },
city: String
});
mongoose.model('Customer', CustomerSchema);
.
.
/**
* Order Schema
*/
var OrderSchema = new Schema({
id : Number,
products: [Schema.Types.Mixed],
total: Number,
comments: String,
customerId: {type: Number, ref: 'Customer'}
});
mongoose.model('Order', OrderSchema);
.
.
exports.customerOrders = function (req, res) {
return Order.find({customerId: req.params.customerId}, function (err, orders) {
Order.populate(orders, {path: 'customerId', model: 'Order'}, function (err, orders) {
if (!err) {
return res.json(orders);
} else {
return res.send(err);
}
});
});
};
the above code generate the following error:
{
message: "Cast to ObjectId failed for value "1" at path "_id"",
name: "CastError",
type: "ObjectId",
value: 1,
path: "_id"
}
the relation between objects is id no _id
Please help me to use the populate method in the right way.
Thanx,
Mongoose's populate functionality only supports using the _id field to find the related doc in the referenced collection.
So you can't use another field like id and you'd need to change customerId to be:
customerId: {type: ObjectId, ref: 'Customer'}
in OrderSchema and then populate it with the _id value of the customer instead.

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