I am unable to update and save a change in the database using mongoose. I am getting the same value for foundProduct twice when I console.log. What could be going wrong?
// Schema
const productSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
onSale: {
type: Boolean,
default: false,
},
}
)
// model
const Product = mongoose.model('Product', productSchema)
const findProduct = async () => {
const foundProduct = await Product.findOne({ name: 'Mountain Bike' });
console.log(foundProduct)
foundProduct.OnSale = true;
await foundProduct.save().then((data) => console.log(data))
// console.log(foundProduct)
}
findProduct();
You have a typo. Change foundProduct.OnSale = true; with foundProduct.onSale = true;.
Since you are using the wrong case, Mongoose considers OnSale to be an extra field. And because it's not in your schema, it's ignored when saving to db.
You have a typo error in the foundProduct.OnSale instead of foundProduct.onSale
Related
I have this code:
module.exports = async (msg) => {
const postId = msg.wall.copyHistory[0].id;
const userId = msg.wall.ownerId;
const bonusePostManager = new BonusePostManager(postId)
const post = await bonusePostManager.getPost(postId);
if (!post) return;
if (post.reposters.includes(userId)) return;
const balanceManager = new BalanceManager(userId, 0);
const doubleCheckReposter = await bonusePostManager.getPost(postId);
if (doubleCheckReposter?.reposters.includes(userId)) return;
bonusePostManager.addReposter(userId)
.catch(console.error)
.then((res) => {
balanceManager.plusBalance(post.bonuseAmount, 'balance').then(async (res) => {
await messageAssistant.sendMessage({
peer_id: userId,
text: `Вы сделали репост, вы получаете ${numberWithSpace(post.bonuseAmount)}`
})
})
})}
If a person makes a repost from two devices at the same time, then the document does not have time to update and allows the possibility of a double repost. I tried using the $addToSet operator:
addReposter(userId, postId = this.postId) {
return Bonuse.updateOne({
id: postId,
}, {
$addToSet: {
'reposters': userId
}
})
}
But it doesn't help, I really don't know how to fix it. I return the promiss everywhere, try to wait for them, but this does not fix the situation, please help me!
I also attach the BonusePost scheme:
const { Schema } = require('mongoose');
const PostSchema = new Schema({
postId: {
type: Number,
unique: true,
index: true
},
active: {
type: Boolean,
default: true,
index: true,
},
bonuseAmount: {
type: Number,
},
reposters: {
type: Array,
default: [],
}
})
module.exports = PostSchema;
And model:
const { model } = require('mongoose');
const PostSchema = require('./schema');
const Bonuse = new model('Bonuse', PostSchema)
module.exports = Bonuse;
I have two collections where one holds list of systems and the other holds list of battery attached to the system. I want to use populate method so that when I run the query using system id it shows me the details of battery is also shown.
My schema for system and battery are as follows.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const SystemSchema = new Schema(
{
serialNumber: String,
location: String,
BPIDs: [
{
type: Schema.Types.ObjectId,
ref: 'batteryPack'
}
]
},
{
timestamps: true
}
);
const Systems = mongoose.model('system', SystemSchema);
module.exports = Systems;
My battery model is as follows:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const batteryPackSchema = new Schema(
{
systemSerialNumber: String,
batteryID: Number,
batteryVoltage: Number,
totalCurrent: Number,
stateOfCharge: Number
{
timestamps: true
}
);
const BatteryPacks = mongoose.model('batteryPack', batteryPackSchema);
module.exports = BatteryPacks;
My query route is as follows:
router.get('/details/:id', async (req, res) => {
try {
const deviceDetails = await Systems.findOne({ _id: req.params.id }).populate('batteryPack').lean();
return res.status(200).send({
deviceDetails
});
} catch (error) {
return res.status(500).send(error.stack);
}
});
On running query through postman it shows the following error:
MongooseError: Cannot populate path batteryPack because it is not in your schema. Set the strictPopulate option to
false to override.
at getModelsMapForPopulate
I was passing wrong argument inside populate method. The code is working flawlessly now.
const deviceDetails = await Systems.findOne({ _id: req.params.id }).populate('BPIDs').lean();
const deviceDetails = await Systems.findOne({ _id: req.params.id },{},{
populate: { path: 'BPIDs' },
lean: true,
})
I'm trying to create a Tumblr clone with GraphQL and MERN. Right now I'm just trying to create the template for posts with photos.
Just in case it's relevant, I am doing regular REST post requests with axios and express for the image files. I take the response from those, map over the _ids and send them in the createPost mutation.
In graphiql I can query for a single Image model and get everything back fine, like so:
{
image(_id: "someId"){
_id
url
created
}
}
But when I do a subquery with the ObjectIds I've pushed into the Post arrays I get null for everything besides _id and __typename:
{
post(_id: "someId"){
_id
mainImages {
_id //returns value
url //returns null
created //returns null
__typename //returns value
}
}
}
The posts have two arrays of objects with ObjectId and ref for images, the Post model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PostSchema = new Schema({
mainImages: [
{
type: Schema.Types.ObjectId,
ref: 'Image'
}
],
bodyImages: [
{
type: Schema.Types.ObjectId,
ref: 'Image'
}
],
})
module.exports = mongoose.model('Post', PostSchema, 'posts')
The Image model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ImageSchema = new Schema({
url: {
type: String,
required: true
},
created: {
type: Date,
required: true
}
})
module.exports = Image = mongoose.model('Image', ImageSchema, 'images');
The PostType:
const PostType = new GraphQLObjectType({
name: 'PostType',
fields: () => ({
_id: { type: GraphQLID },
mainImages: {
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('images')
.then(post => post.mainImages)
}
},
bodyImages: {
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('images')
.then(post => post.bodyImages)
}
},
})
})
module.exports = PostType;
I'm wondering if .populate('images') isn't working correctly. I thought that if you have the ObjectIds then .populate() can take care of the rest. I've been looking around at a bunch of different questions but none of them have seemed to be relevant enough to my situation, and the GraphQL and Mongoose docs also haven't given me a breakthrough yet.
Alright so in the latest edition of I wasn't reading the docs correctly, I finally figured out what I was doing wrong.
.populate() takes a string that denotes a path to the field within the document that you're trying to populate the field of.
I figured out the solution while I was reading about populating multiple fields in a single document.
For some reason I thought the 'path' was supposed to point to the name of the collection in the database:
const PostType = new GraphQLObjectType({
name: 'PostType',
fields: () => ({
_id: { type: GraphQLID },
mainImages: {
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('images') //incorrectly pointing towards the collection in db
.then(post => post.mainImages)
}
},
bodyImages: {
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('images') //incorrectly pointing towards the collection in db
.then(post => post.bodyImages)
}
},
})
})
module.exports = PostType;
It's supposed to point back in to the document/model itself:
const PostType = new GraphQLObjectType({
name: 'PostType',
fields: () => ({
_id: { type: GraphQLID },
mainImages: { //this is the 'path'
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('mainImages') //that's referenced here
.then(post => post.mainImages)
}
},
bodyImages: {
type: new GraphQLList(ImageType),
resolve(parentValue) {
return Post.findById(parentValue._id)
.populate('bodyImages') //and once again
.then(post => post.bodyImages)
}
}
})
})
export default PostType;
And that solved my problem, all of my GraphQL subqueries are working correctly now. Another day, another episode of I didn't read the docs correctly.
I'm trying a to make a post request to save new data to one of my subdocuments, but I'm getting an error when trying to access the subdocument in the function. It keeps coming back as undefined. How can I get a specific user by id and create and add new data the one it's subdocuments?
model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ClassworkSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false
});
const OutcomesSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false,
isApproved: false
})
const MeetupSchema = new Schema({
name: String,
time: Date,
location: String,
attended: false
})
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
classwork:{type: [ClassworkSchema], default: []},
outcomes: [OutcomesSchema],
meetups: [MeetupSchema],
});
module.exports = User = mongoose.model('users', UserSchema);
controller
classworkRouter.post("/:userId/", (req, res) => {
User.findById(req.params.user_id, (err, user) => {
if (err) return err;
new_classwork = new classwork();
(new_classwork.name = req.body.name),
(new_classwork.date = req.body.date),
(new_classwork.todo = req.body.todo),
(new_classwork.isDone = req.body.isDone);
console.log(new_classwork);
user.classwork = {};
user.classwork.name = req.body.classwork.name;
user.classwork.todo = user.classwork.todo;
if (user.classwork === undefined) {
user.classwork.push(new_classwork);
} else {
user.classwork = [new_classwork];
}
user.save(function (err, data) {
if (err) res.send(err);
res.json({ message: "work added", data: data });
});
});
});
you can see the error in the terminal in the following phto:
in this part of code
new_classwork = new classwork()
you shoud defined the new_classwrok like this :
let new_classwork = new classwork()
and new classwork() is not defined, you must to require Model of classwork in controller..
in schema file export schemas like this :
const User = mongoose.model('users', UserSchema);
const Classwork = mongoose.model('Classwork', ClassworkSchema );
module.exports = {
User : User ,
Classwork : Classwork
}
in controller.js
const {User} = require('../models/certification');
const {Classwork } = require('../models/certification');
after require models you can use new Crosswork like this :
note: Classwork with uppercase character
let new_classwork = new Classwork()
I am trying to delete a MongoDB document but it's not getting deleted
My schema is
const mongoose = require("mongoose");
const InvestorSchema = mongoose.Schema({
name: {
type: String,
index: true,
required: true
},
logoUrl: {
type: String,
required: true
},
website: {
type: String,
index: true,
unique: true,
required: true
}
});
module.exports = mongoose.model("Investor", InvestorSchema);
and I tried using these but none of them removed the document, Also i'm running on localhost with no users and roles.
// Required models
const InvestorModel = require("mongoose").model("Investor");
const deletedInvestor = InvestorModel.remove({ _id });
const deletedInvestor = InvestorModel.deleteOne({ _id });
const deletedInvestor = InvestorModel.findByIdAndRemove(_id);
const deletedInvestor = InvestorModel.findOneAndRemove({_id});
const deletedInvestor = InvestorModel.findByIdAndDelete(_id);
const deletedInvestor = InvestorModel.findOneAndDelete({_id});
How do i solve this?
try {
InvestorModel.deleteOne( { "_id" : ObjectId("563237a41a4d68582c2509da") } );
} catch (e) {
console.log(e);
}
here the problem is you don't specify what object from the collection you want to remove...
So you should use your code implementation like this mate
InvestorModel.remove({ _id: '563237a41a4d68582c2509da' },callback);
InvestorModel.deleteOne({_id: '563237a41a4d68582c2509da' },callback);
InvestorModel.findByIdAndRemove({_id: '563237a41a4d68582c2509da'},callback);