Unable to save to an asssociate array in mongodb using mongoose - javascript

var mongoose = require("mongoose"),
campground = require("./models/campground"),
comment = require("./models/comment");
var data = [{
name: "Offside Lake",
image: "https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Whatever evrr"
},
{
name: "Reality Check",
image: "https://images.unsplash.com/photo-1517824806704-9040b037703b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "wabdiwyu"
},
{
name: "Wawu Land",
image: "https://images.unsplash.com/photo-1508873696983-2dfd5898f08b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Just be feeling Wawu"
}
];
var text = {
text: "Hullabaloo",
author: "Olalaa"
};
campground.comments = new Array();
function seedDB() {
campground.deleteMany({}, function(err) {
if (err) {
console.log(err);
} else {
console.log("removed");
data.forEach(function(camp) {
campground.create(camp, function(err, camp) {
if (err) {
console.log(err);
} else {
console.log("Successfully added");
comment.create(text, function(err, comment) {
if (err) {
console.log(err);
} else {
campground.comments.push(comment);
campground.save();
console.log("comment added");
}
});
}
});
});
}
});
}
I have two mongoose models campground and comment. Inside the campground schema, I have the comments associative array in the campground schema. I am trying to add comments to my comments array but I am getting the error - campground.save is not a function. Even tried campground.markModified("comment") then campground.save(), getting the same error
//my campground schema
var mongoose = require("mongoose");
var campSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "comment"
}]
});
module.exports = mongoose.model("Camp", campSchema);
//my comment schema
var mongoose = require("mongoose");
var commentSchema = mongoose.Schema({
text: String,
author: String
})
module.exports = mongoose.model("comment", commentSchema);

If I understand what you are trying to do, you are trying to create a campground and place the comments inside.
If that is so, then the code may look something like this (placed everything in one file):
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
var data = [
{
name: "Offside Lake",
image: "https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Whatever evrr"
}, {
name: "Reality Check",
image: "https://images.unsplash.com/photo-1517824806704-9040b037703b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "wabdiwyu"
}, {
name: "Wawu Land",
image: "https://images.unsplash.com/photo-1508873696983-2dfd5898f08b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
description: "Just be feeling Wawu"
}
];
const comment = mongoose.model('comment', new mongoose.Schema({
text: String,
author: String
}));
const campground = mongoose.model('Camp', new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "comment"
}]
}));
var text = {
text: "Hullabaloo",
author: "Olalaa"
};
campground.deleteMany({}, function(error) {
if (error) {
console.error(error);
return;
}
console.log("Removed");
data.forEach(function(camp) {
campground.create(camp, function(error, newCamp) {
if (error) {
console.error(error);
return;
}
console.log("Successfully added");
comment.create(text, function(err, newComment) {
if (err) {
console.error(err);
return;
}
newCamp.comments.push(newComment);
newCamp.save();
console.log("Comment added");
})
});
})
})
The problem was due to the fact that you kept the same name throughout and that might have confused you a bit.
What you wanted to do was camp.comments.push(comment) camp.save() instead of campground.comments.push(comment) and campground.save() respectively.
As a friendly advice:
Switch to using promises instead of callbacks, you may set yourself up for what is known as Callback hell
As much as possible try not to rely on the closure nature of JavaScript and keep naming your variables the same throughout. That leads to problems like what you are experiencing now

Related

MongoDB Cannot read property 'push' of undefined

I'm new to node.js, express and MongoDB, and still learning. The program had a runtime error when I tried some data association in MongoDB models. The reference has been included in the model already but push() method can't recognize it. The models look like this:
var mongoose = require('mongoose');
var commentSchema = new mongoose.Schema({
text: String,
author: String
});
var Comment = mongoose.model("comments", commentSchema);
module.exports = Comment;
and
var mongoose = require('mongoose');
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]
});
var Campground = mongoose.model("campgrounds", campgroundSchema);
module.exports = Campground;
The part where these two models are needed looks like this:
Campground.remove({}, function(err){
if(err){
console.log(err);
}else{
console.log("removed campground!");
data.forEach(function (seed) {
Campground.create(seed, function (err, data) {
if(err){
console.log(err);
} else{
console.log("camp created");
Comment.create(
{
text: "nice campsite!",
author: "haiderboi"
},function (err, comment) {
if(err){
console.log(err);
}else{
Campground.comments.push(comment);
Campground.save();
console.log("comment added");
}
}
);
}
});
});
}
});
It seems like the array is already defined in the Campground model so I can't tell the error. Thanks in advance!
Hey i was have problem like this in my project.And it wasn't working because my blogpost schema was like this:
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}
]});
And changed it to this:
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String,
comments: [
{
type: mongoose.Schema.Types.Mixed,
}
]});
Because up there you're referring ObjectId and you're setting an object inside your code.It's not match.So you should try like this
Found the problem!
Instead of doing
Campground.comments.push(comment);
I should do
data.comments.push(comment);
since I wanna push the comment to the current Campground object, I should use the object returned by the callback.

Node.js, MongoDB error - "message": "Schema hasn't been registered for model \"Category\".\nUse mongoose.model(name, schema)"

I'm in process of an app based on Node.js, MongoDB and Express. My goal is to get a fetch API system to work.
When using Postman to check out my status, the GET for "article.js" model file (in my localhost:3000/articles) shows the following error:
{
"error": {
"message": "Schema hasn't been registered for model \"Category\".\nUse mongoose.model(name, schema)",
"name": "MissingSchemaError"
}
}
This error disables the display of my articles or categories in Postman, as they are saved in my MongoDB project area at mongodb cloud.
The model file code "article.js" is the following:
const mongoose = require('mongoose');
const articleSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
description: { type: String, required: true },
content: { type: String, required: true },
categoryId: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'Category' }
});
module.exports = mongoose.model('Article', articleSchema);
This file connects with the controller named "articles.js", with the following relevant code:
const mongoose = require('mongoose');
const Article = require('../models/article');
const Category = require('../models/category');
module.exports = {
getAllArticles: (req, res) => {
Article.find().populate('categoryId', 'title').then((articles) => {
res.status(200).json({
articles
})
}).catch(error => {
res.status(500).json({
error
})
});
},
createArticle: (req, res) => {
const { title, description, content, categoryId } = req.body;
Category.findById(categoryId).then((category) => {
if (!category) {
return res.status(404).json({
message: 'Category not found'
})
}
const article = new Article({
_id: new mongoose.Types.ObjectId(),
title,
description,
content,
categoryId
});
return article.save();
}).then(() => {
res.status(200).json({
message: 'Created article'
})
}).catch(error => {
res.status(500).json({
error
})
});
},
}
The model file "category.js" code in the app looks like this:
const mongoose = require('mongoose');
const categorySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
description: { type: String, required: true }
});
module.exports = mongoose.model('Category', categorySchema);
I looked up topics from the past here, such as this one - but it didn't solve my problem.
What should I do in order to fix my code?
Is it a syntax mistake or something else?
the code seems to be OK
I don't see here any particular error's

unhandled promise rejection warning - couldn't store into database

Data comming from req is store in Comment collection but it is not store in Product collection and i'll get an error message
app.post("/products/:id/comments", function(req, res) {
//lookup campground using ID
Product.findById(req.params.id, function(err, product) {
if (err) {
console.log(err);
res.redirect("/products");
} else {
Comment.create(req.body.comment, function(err, comment) {
if (err) {
console.log(err);
} else {
console.log("aaaaaa");
product.comments.push(comment);
console.log("bbbbbb");
product.save();
console.log("cccccc");
res.redirect('/products/' + product._id);
}
});
}
});});
and following is Product
var mongoose = require("mongoose"),
productSchema = new mongoose.Schema({
name: String,
img: String,
price: Number,
desc: String,
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
}],
created: {
type: Date,
default: Date.now()
}});module.exports = mongoose.model("Product", productSchema);
and this is Comment Schema
var mongoose = require("mongoose"),
commentSchema = mongoose.Schema({
text: String,
author: String
});module.exports = mongoose.model("Comment", commentSchema);
and i got following output :-
enter image description here
so it's store in commentSchema but it's not store in product.comments and when i run site that also redirect to products/:id, what i'm missing to store comment into database ??
If you don’t pass a callback function to save() then it will return a promise.
Therefore, you are getting the error as you have not added a catch.
Try passing a callback to save():
// ...
product.save(function(err, result) {
if (err) {
// Handle error
}
console.log("cccccc");
res.redirect('/products/' + product._id);
})

mongodb Error mongoose do not push object in array $pushAll

I have a simple app with User and Post models,
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/assoc", {useMongoClient:true});
mongoose.Promise = global.Promise;
//Post
var postSchema = new mongoose.Schema({
title: String,
content: String
});
var Post = mongoose.model("Post", postSchema);
//User
var userSchema = new mongoose.Schema({
email: String,
name: String,
posts: [postSchema]
});
var User = mongoose.model("User", userSchema);
I Create a user before (name: "gino") and push a post into:
// var newUser = new User({
// email: "a.b#c.it",
// name: "gino"
// });
//
// newUser.posts.push({
// title: "gino's post",
// content: "this is content"
// });
//
// newUser.save(function (err, user) {
// if (err) {
// console.log(err);
// } else {
// console.log(user);
// }
// });
Also create another post to check if Post model works:
// var newPost = new Post({
// title: "honky",
// content: "tonky"
// });
//
// newPost.save(function (err, post) {
// if (err) {
// console.log(err);
// } else {
// console.log(post);
// }
// });
When I try to find "gino" and push a new item into the posts array I have an error trying to save user (user.save) with this snippet:
User.findOne({name: "gino"}, function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
user.posts.push({
title: "post",
content: "content"
});
user.save(function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
}
});
}
});
When I run the app i got this:
{ MongoError: Unknown modifier: $pushAll
at Function.MongoError.create (appFolder\node_modules\mongodb-core\lib\error.js:31:11)
at toError (appFolder\node_modules\mongodb\lib\utils.js:139:22)
at appFolder\node_modules\mongodb\lib\collection.js:1059:67
at appFolder\node_modules\mongodb-core\lib\connection\pool.js:469:18
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
name: 'MongoError',
message: 'Unknown modifier: $pushAll',
driver: true,
index: 0,
code: 9,
errmsg: 'Unknown modifier: $pushAll' }
Someone can help me?
Try using findOneAndUpdate instead.
User.findOneAndUpdate(
{ name: "gino" },
{ $push: { posts: { title: 'post', content: 'content' } } },
{ new: true },
function (err, user) {
if(err) console.log("Something wrong when updating data");
console.log(user);
});
Hope it helps!
If you are using 3.5 MongoDB version or higher, can be an issue with $pushAll, which is deprecated.
I founded an option to work around setting usePushEach to true:
new Schema({ arr: [String] }, { usePushEach: true });
Founded in:
https://github.com/Automattic/mongoose/issues/5574#issuecomment-332290518
Can be useful to use the with .push.

issues with count property of object inside object or array

I try to count property of one object inside another but get a wrong value: I want to count the object inside property of productInfo of order object which is 15 but my function return 46.
router.get("/product", isLoggedIn, function (req, res) {
products.find({}, function (err, products) {
if (err) {
console.log("ERROR!");
} else {
orders.find({
customerInfo: req.user
}, function (err, orders) {
if (err) {
console.log("ERROR!");
} else {
res.render("allProduct", {
data1: _.keys(orders[0].productInfo).length,//here object must counted!
data:products
});
}
});
}
});
});
and here are my models:
var mongoose = require("mongoose");
var order = new mongoose.Schema({
orderNo: Number,
customerInfo: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}],
productInfo: [{
type: mongoose.Schema.Types.ObjectId,
ref: "product"
},]
});
//EXPORT
module.exports = mongoose.model("order", order);
and:
var mongoose =require("mongoose");
var product = new mongoose.Schema({
productNo: Number,
productName: String,
productDes:String,
productPrice:Number,
});
//EXPORT
module.exports = mongoose.model("product",product);
I solve this issues with replace :
_.keys(orders[0].productInfo).length,
with:
orders[0].productInfo.length

Categories

Resources