How to auto delete ObjectId referances in mongodb - javascript

im trying to auto delete notifications referance from users ,when notification gets deleted
the userSchema looks like
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
notifications: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Notification",
},
],
});
module.exports = mongoose.model("User", userSchema);
The notification model looks like this
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
this.model("User").deleteOne({ notifications: this._id }, next);
});
module.exports = mongoose.model("Notification", notificationSchema);
when i try to delete notification i get an error ,which looks like
ObjectParameterError: Parameter "obj" to Document() must be an object, got User
also is there a way to auto delete it [referances of notification in user] using TTL for notifications

ok ,after a few try and error. I came up with this solution..
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
let id = this.getQuery()["_id"];
mongoose.model("User").findOne(
{
notifications: id,
},
(err, res) => {
const index = res.notifications.findIndex((x) => x._id == id);
res.notifications.splice(index, 1);
res.save();
next();
}
);
});
module.exports = mongoose.model("Notification", notificationSchema);
Can i make any improvements ?

Related

How to populate using mongoose? I have a problem

I'm making a simple example of CRUD for a larger and open source project. Right now I want to populate with user data, I have already looked at the documentation and some forums and I am not able to solve the problem that is causing here.
The message in terminal "Populated User undefined"
Could anyone help?
userModel
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: {
type: String
},
});
userController
var mongoose = require('mongoose'),
User = mongoose.model('Users');
exports.create_a_user = function(req, res) {
var new_user = new User(req.body);
new_user.save(function(err, user) {
if (err)
res.send(err);
res.json(user);
});
};
msgModel
module.exports = mongoose.model('Users', userSchema);
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var msgSchema = new Schema({
title: {
type: String
},
body: {
type: String
},
created_date: {
type: Date,
default: Date.now
},
user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
});
module.exports = mongoose.model('Messages', msgSchema);
msgController
var mongoose = require('mongoose'),
Message = mongoose.model('Messages');
exports.list_all_messages = function (req, res) {
Message.find({})
.populate('user')
.exec((err, msg) => {
if (err)
res.send(err);
res.json(msg);
});
};
module.exports = mongoose.model('Users', userSchema);
maybe in msgSchema you have to reference 'users' instead of 'user'
So, I found the error in the code, in the user's schema there was a lack of reference to the export of the name that was placed in the user's model.
user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
So,...
module.exports = mongoose.model('Users', userSchema);

is there a method to execute a function after a spesific condition in express js

for exemple I have a user model like this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
username: {
type: String,
required: true,
},
Points: {
type: Number,
default: 0,
},
module.exports = User = mongoose.model("users", UserSchema);
then I want to execute a function automatically when user.points is equal to 10 with express js, is there any solution ?
#Yessine, may you should try something like this. You can add checkForPoints wherever you are updating the Points and proceed with your things,
const { Users } = require('/schema.js');
const checkForPoints = async (username) => {
await Users.findOne({ username }, function (err, data) {
if (err) {
console.log("enter error ------", err)
}
if (data && data.Points === 10) {
// Execute your code
}
});
};
// Users schema(schema.js)
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('your db', { useNewUrlParser: true });
const requestSchema = mongoose.Schema({
_id: mongoose.Types.ObjectId,
username: String,
Points: Number
});
module.exports = mongoose.model('users', requestSchema);
Polling is a technique where we check for fresh data over a given interval by periodically making API requests to a server.enables you to periodically check for the newest values of data and do further requests once it enters the desired state.

Building API for model that has referenced attribute

so my question is how can i display data of a model that has an attribute reference to another model? In this task i have Driver model that has attribute state which should reference another model called State that has a name attribute. I know hot to reference models in mongoose but i don't know how to build API for creating new Driver and displaying it.
Below is my Driver and State models
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Driver = new Schema({
name: {
type: String
},
phone: {
type: String
},
email: {
type: String
},
deleted: {
type: Boolean
},
state: {
type: Schema.ObjectId,
Ref: 'State'
}
});
module.exports = mongoose.model('Driver', Driver);
This is model of State
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let State = new Schema({
name: {
type: String
}
});
module.exports = mongoose.model('State', State);
Currently my API are looking like this
driverRoutes.route('/').get(function(req, res){
Driver.find(function(err, drivers){
if(err){
console.log("Error");
} else {
res.json(drivers);
}
});
});
driverRoutes.route('/:id').get(function(req, res){
let id = req.params.id;
Driver.findById(id, function(err, temp){
res.json(temp);
});
});
driverRoutes.route('/add').post(function(req, res){
let temp = new Driver(req.body);
temp.save()
.then(temp =>{
console.log(temp.state);
res.status(200).json({'driver': 'driver added successfully'});
})
.catch(err => {
res.status(400).send('adding new driver failed');
});
});
Route with / is to display all Drivers in table.
Change your Driver model to look as below,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Driver = new Schema({
_id: {
type:Schema.Types.ObjectId
},
name: {
type: String
},
phone: {
type: String
},
email: {
type: String
},
deleted: {
type: Boolean
},
state: {
type: Schema.Types.ObjectId, //this is the change made
Ref: 'State'
}
});
module.exports = mongoose.model('Driver', Driver);
The second step is optional. That is, in your state model,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let State = new Schema({
_id:{
type:Schema.Types.ObjectId //this is optional however
},
name: {
type: String
}
});
module.exports = mongoose.model('State', State);
That should help.

How can I create a post, i have two mongoose models ref'ing each other

Basically I wanna create a Post that has its author to the users name, the one who created it. I also want the Post to be pushed into the array of posts, which the user model has, that is ref'ing to "Post".
I have been googling and watching youtube videos but still i do not understand how i would go about to do this, also i read about populate, but i wanna create a new post and have the author to be the users name, also i want the post to be pushed into the array of posts that the user has.
How would I go about doing this ?
This is the post create controller
exports.postCreatePost = (req, res, ) => {
const {
title,
description,
context
} = req.body;
const post = new Post({
title,
description,
context,
author:
})
}
This is the model.js
const mongoose = require("mongoose"),
Schema = mongoose.Schema,
bcrypt = require("bcryptjs");
const postSchema = new Schema({
title: String,
description: String,
context: String,
author: {
type: Schema.Types.ObjectId,
ref: "User"
}
});
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true
},
posts: [{
type: Schema.Types.ObjectId,
ref: "Post"
}]
});
userSchema.pre("save", async function save(next) {
const user = this;
if (!user.isModified("password")) return next();
const hashedPassword = await bcrypt.hash(user.password, 10);
user.password = hashedPassword;
next();
});
const Post = mongoose.model("Post", postSchema);
const User = mongoose.model("User", userSchema);
const userId = new mongoose.Types.ObjectId();
Either let client send you username/id and get it from req.body or when you are authenticating user simply pass the reference to the user to the body of request.
For example when client gives you id/username you can do something like this
const post = new Post({
title,
description,
context,
author: req.body.username or req.body.id
})
If you want to push use this
await findOneAndUpdate({_id: req.body.id}, {
"$push":
{
"posts": post._id
}
})

How do I match and post id to a comment in mongoose populate for find({})

I am trying to get comments from one collections and link them to their specific post.
What I want to do is find all of the posts instead of the collections THEN populate each of the commentid's in post collections with matching comments inside the comment collections.
I have set articleid to be the same as the post _id manually with an an ajax request function. However I am getting confused with how to properly use match in populate.
Ex. post _id 123, I want all comments with articleid, 123, but for multiple id's not just one.
I looked at the mongoose docs about populate and there wasn't anything as in depth as this example.
router.get('/displayPosts', (req, res) => {
Post.find({}, 'topic title url', () => {
})
.populate({
path: 'commentId',
// ---------------Where confused
// match: { postId: _id },
select: 'comment',
options: {limit: 5}
})
.sort({createdAt: 'desc'})
.then((data) => {
console.log(data);
res.send({response: data});
});
});
});
//when generating new docs
//getting this from bodyparser from button submit
const newComment = new Comments({
comment: req.body.userComment,
articleId: req.body.id
});
newComment.save();
const newArticle = new Article({
topic: data.topic,
title: data.title,
url: data.url
});
newArticle.save();
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Comments = require('./comments');
const PostSchema = new Schema({
topic: String,
title: String,
url: String,
commentId: [{type: Schema.Types.ObjectId, ref: 'Comments'}]
},
{
timestamps: true
});
const Post = mongoose.model('Post', ArticleSchema);
module.exports = Post;
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Post = require('./articles');
const CommentSchema = new Schema({
comment: String,
articleId: String
},
{
timestamps: true
});
const Comments = mongoose.model('Comments', CommentSchema);
module.exports = Comments;

Categories