how to delete referenced value in mongoose schema - javascript

const UniversitySchema = new Schema({
university_name: {
type:String,
},
status: {
type: String
}
});
const CollageSchema = new Schema({
collage_name: {
type:String,
required: [true,'Name field is required']
},
university_id: {
type: [{ type: Schema.Types.ObjectId ,
ref: 'university' }]
},
type: {
type:String
}
});
router.delete('/university/:id',function(req,res,next){
University.findByIdAndRemove({_id:req.params.id}).then(function(detail){
res.send(detail);
});
});
I have referenced _id of UniversitySchema in CollageSchema and if I delete any university corresponding collage should be deleted. How to do this?

With an additional mongo call on collages collection, using Promise.all() :
router.delete('/university/:id',function(req,res,next){
const ObjectId = require('mongodb').ObjectId;
const _id = ObjectId(req.params.id);
const removeUniversity = University.findByIdAndRemove({ _id: _id });
const removeCollage = Collage.remove({ university_id: _id });
Promise
.all([removeUniversity, removeCollage])
.then(function(values) {
const detail = values[0];
res.send(detail);
})
.catch((err) => console.error(err));
});

Related

Mongoose populate replacing ObjectIds with empty array

I've been trying to use the mongoose populate function to connect two models. I can save an object but when trying to retrieve using populate the ObjectIds are just replaced with an empty array.
Many questions seem to have been asked but none have a solution that worked for me
user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Route = require('./route')
var passportLocalMongoose = require('passport-local-mongoose');
const postSchema = new Schema ({
text: {
type: String,
default: '',
required: true
}
}, {
timestamps: true
});
const UserSchema = new Schema({
firstname: {
type: String
},
posts: [postSchema],
route: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Route'
}]
}, {
timestamps: true
});
UserSchema.plugin(passportLocalMongoose);
const User = mongoose.model('User', UserSchema);
module.exports = User;
route.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const locationSchema = new Schema ({
id: {
type: Number,
default: 0,
required: true
},
address: {
type: String,
default: '',
required: true
},
lat: {
type: Number,
default: 0,
required: true
},
lng: {
type: Number,
default: 0,
required: true
}
},{
timestamps: true })
const routeSchema = new Schema ({
locations: [locationSchema],
description: {
journey1: {
type: String,
default: '',
required: false
},
journey2: {
type: String,
default: '',
required: false
},
journey3: {
type: String,
default: '',
required: false
},
journey4: {
type: String,
default: '',
required: false
}
}
}, {
timestamps: true
});
module.exports = mongoose.model('Route', routeSchema);
within REST POST end point
User.findOne({_id: req.user._id}, function(err,user) {
if(user) {
var routed = new Route();
routed.locations = req.body.locations;
routed.description = req.body.description;
user.route.push(routed);
user.save()
.then((user) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json')
res.json(user)
}, (err) => next(err))
} else {
console.log("errored")
err = new Error('User ' + req.body.username + ' not found');
err.status = 404;
return next(err);
}
})
within REST GET end point
User.findOne({_id: req.user._id})
.populate('route')
.then((user) => {
if(user){
console.log("user")
console.log(user)
console.log("routes")
console.log(user.route)
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json')
res.json({success: true, routes: user.route});
}
}, (err) => next(err))
.catch((err) => next(err));
If I remove populate I'll get something like
[
new ObjectId("61f053af7ba46267f4893f8f")
new ObjectId("61f053af7ba46267f4893f8f")
new ObjectId("61f053af7ba46267f4893f8f")
]
from the GET end point but adding it back in returns
[].
My understanding is that in 'new Route()' I'm creating a new Route Object with an Id that gets stored in the User model/document(?). Then when I call populate mongoose searches the Route document for those Ids and converts them to the objects I want. The only issue I could think of is that I'm not creating the Route objects correctly and so no object is being stored with that Id which is why an empty array is returned when I come to try swap Ids with Route objects.
Any ideas or are we all just stumbling in the dark ?
Not entirely sure this is the correct method but instead of instantiating a Route object as displayed I used the Route.create(...) method and then pushed that to the route array and now populate works as expected

Delete nested object with mongoose

I got this mongoose schemas:
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
groups: [
{
groupName: {
type: String,
required: true,
},
groupMembers: [{ type: Schema.Types.ObjectId, ref: "GroupMember" }],
},
],
});
const GroupMemberSchema = new Schema({
firstName: String,
lastName: String,
birthday: Date,
gender: String,
age: Number
});
I want to have 2 routes:
Delete a group member from the groupMembers array based on objectId.
Delete a whole group from the groups array based on objectId.
My attempt for the delete group member route. This route removes the group member from the groupMembers collection succesfully, but the group member still exist in the user collection:
router.delete(
"/:userId/:groupId/:groupMemberId",
catchAsync(async (req, res) => {
const { userId, groupId, groupMemberId } = req.params;
await GroupMember.findByIdAndDelete(groupMemberId);
const user = await User.findById(userId);
const group = user.groups.find((group) => group._id.toString() === groupId);
const groupIndex = user.groups.indexOf(group);
const updatedGroupmembers = user.groups[groupIndex].groupMembers.filter(groupMember=> groupMember._id.toString()!==groupMemberId);
res.send({updatedGroupmembers})
})
);
Did you try using $pull?
router.delete(
'/:userId/:groupId/:groupMemberId',
catchAsync(async (req, res) => {
const { userId, groupId, groupMemberId } = req.params;
await GroupMember.findByIdAndDelete(groupMemberId);
const updatedUser = await User.findByIdAndUpdate({ id: userId }, { $pull: { groups: groupId } }, { new: true });
res.send({ updatedUser });
}),
);

Can't pass multiple documents in an array when using findById

I want to find each of the elements in the array by their id and send it with the post request to create a new post. Right now when I create a new post only passes the first index of the array and if I use find() it passes all of the social schemas regardless if it is in the body of the request. I hope this makes sense if it doesn't please let me know. I hope someone can help.
Below is the mongoose schema for the qrcode post also using Joi
const Joi = require("joi");
const mongoose = require("mongoose");
const { themeSchema } = require("./Theme");
const { userSchema } = require("./User");
const { socialSchema } = require("./Social");
const QrCode = mongoose.model(
"QrCode",
new mongoose.Schema({
user: {
type: userSchema,
required: true,
},
name: {
type: String,
maxLength: 255,
required: true,
trim: true,
},
theme: {
type: themeSchema,
required: true,
},
// Social Media Links
social: [
{
type: socialSchema,
required: true,
},
],
})
);
function ValidateQrCode(qrCode) {
const schema = {
userId: Joi.objectId(),
name: Joi.string().max(255).required(),
themeId: Joi.objectId().required(),
socialId: Joi.array().required(),
};
return Joi.validate(qrCode, schema);
}
module.exports.QrCode = QrCode;
module.exports.validate = ValidateQrCode;
this is the post route to create a new qrcode
router.post("/", auth, async (req, res) => {
const { error } = validate(req.body);
if (error) res.status(400).send(error.details[0].message);
const theme = await Theme.findById(req.body.themeId);
if (!theme) return res.status(400).send("Invalid theme.");
const user = await User.findById(req.user._id);
if (!user) return res.status(400).send("Invalid theme.");
const social = await Social.findById(req.body.socialId);
if (!social) return res.status(400).send("Invalid social.");
const qrCode = new QrCode({
user: user,
name: req.body.name,
theme: theme,
social: social,
});
await qrCode.save();
res.send(qrCode);
});
In the body of my Postman request I am inputting the info below
{
"name": "Friends",
"themeId": "60f89e0c659ff827ddcce384",
"socialId": [
"60f89e43659ff827ddcce386",
"60f89e5c659ff827ddcce388"
]
}
To fetch data using ids, you can use below mongodb query simply,
db.collection.find( { _id : { $in : ["1", "2"] } } );
In mongoose,
model.find({
'_id': { $in: [
mongoose.Types.ObjectId('1'),
mongoose.Types.ObjectId('2'),
mongoose.Types.ObjectId('3')
]}
}, function(err, docs){
console.log(docs);
});
Or
await Model.find({ '_id': { $in: ids } });

Mongoose "find" returns an empty array

i'm trying to find all blogs that a user has created with his userId.
I have the following mongoose model for the blog
var mongoose = require('mongoose');
var BlogSchema = new mongoose.Schema({
title:{
type: String,
required: true,
},
content:{
type: String,
required: true
},
_creator:{
type: mongoose.Schema.Types.ObjectId,
required: true
}
})
BlogSchema.statics.findBlogs = function(id){
var Blog = this;
return Blog.find(id).then((blog)=>{
console.log(blog)
}).catch((e)=>{
console.log('failed')
})
}
var Blog = mongoose.model('Blogs', BlogSchema)
module.exports = {Blog};
then in my server.js i have this
app.get('/get/blogs', authenticate, (req, res)=>{
var userId = req.user._id
console.log(userId)
Blog.findBlogs(userId).then((data)=>{
res.send(data)
}).catch((e)=>{
res.sendStatus(404)
})
})
but it returns an empty array, how should i approach this?
The line
return Blog.find(id).then((blog) => {
should probably say
return Blog.find({ _creator: id }).then((blogs) => {
Try this
blog.find({creatorid:user.id},function(err,data){
//data will be here
})

How to make post request to child attribute

How do i make a post request to the product {type: mongoose.Schema.Types.ObjectId, ref: 'Product'} in my schema this is what my schema looks like
const CategorySchema = mongoose.Schema({
name: {
type: String,
required: true
},
img_url:{
type:String,
required: true
},
product: [
{type: mongoose.Schema.Types.ObjectId, ref: 'Product'}
]
})
but i don't know how i can post to the product array?
router.post('/',(req,res)=>{
const newCategory = newCategory()
category.name = req.body.name;
category.img_url = req.body.img_url;
Category.save(newCategory,(err,category)=>{
if (err) {
console.log(err);
}else {
res.json(status: true)
}
})
})
Where have you defined the category? Try this:
router.post('/',(req,res)=>{
var category = new Category() //assuming you defined newCategory as a call to the model
category.name = req.body.name;
category.img_url = req.body.img_url;
category.save((err,category)=>{ //here you're saving the
if (err) {
console.log(err);
}else {
res.json(status: true)
}
})
})

Categories

Resources