I want to trigger a remove operation to a ModelB inside a mongoose pre.save hook from a ModelA.
Basically any time any ModelA is updated, I need to drop the ModelB collection:
This is what I tried, I don't get errors but the operations never ends:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = Schema.Types.ObjectId;
const permissionSetSchema = require('./permission-set');
const PermissionSet = mongoose.model('PermissionSet', permissionSetSchema);
const roleSchema = new Schema({
name : { type: String, required: true, unique: true, maxLength: 140 },
description: { type: String, maxLength: 300 },
});
roleSchema.post('update', (next, done) => {
PermissionSet.remove({}, err => {
if (err) { next(err); }
next();
});
});
The first arg is the document. The second is the next callback.
Should be:
roleSchema.post('update', (doc, next) => {
PermissionSet.remove({}, err => {
if (err) { next(err); }
next();
});
});
http://mongoosejs.com/docs/middleware.html
Related
I want to create a document in my MongoDB database and take the _id of the new document.
This is what I'm doing:
const mongoose = require("mongoose");
const billingSchema = require("./models/billing");
const { ObjectId } = require("bson");
const { MongoClient } = require("mongodb");
const mongouri = "***";
var connection = mongoose.createConnection(mongouri);
var Bills = connection.model("Fatturazione", billingSchema, "Fatturazione");
exports.createBill = (b) => {
return new Promise((resolve, reject) => {
Bills.Create(b, function (err) {
if (err) {
reject(err);
} else {
console.log(mongoose.Types.ObjectId(b._id));
resolve();
}
});
});
};
and this is my Schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
//schema define the structure of the document
const billingSchema = new Schema({
data_fatturazione: {
type: Date,
required: true,
},
data_saldo: {
type: Date,
required: false,
},
totale: {
type: Number,
required: false,
},
pagato: {
type: Boolean,
required: false,
},
});
module.exports = billingSchema;
In the console.log() I want to print the _id of the last inserted document but it prints a non-existing id (it doesn't correspond to the _id of the last created document in the database). I also tried without using mongoose.Types.ObjectId() but it prints undefined. I don't understand where is the problem.
I call the function createBill() in another js file, passing an object with the correct fields.
You are trying to get the _id of argument b, which is passed to your createBill, which is logically undefined. Instead you must get the _id from a result of Bill.create, mongoose callbacks take 2 arguments as #Joe mentioned in the comments, so your code must look like this:
exports.createBill = (b) => {
return new Promise((resolve, reject) => {
Bills.Create(b, function (err, result) {
if (err) {
reject(err);
} else {
console.log(result._id);
resolve(result);
}
});
});
};
exports.clearHours = (req, res, next) => {
Hour
.find({ user: req.body.userId })
.then(hour => {
for (let i=0;i<hour.length;i++) {
hour[i].hours = 0;
}
return hour.save()
})
.then(result => {
res.status(200).json({message: 'Working hours have been successfully updated.'});
})
.catch(err => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
})
};
I am trying to save the formatted array on the database and I get this error. The updated code is passed properly but when I am trying to save the array it comes up with this error. Any ideas why?
This is my hour model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const hourSchema = new Schema ({
day: {
type: String,
required: true
},
hours: {
type: Number,
required: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
});
module.exports = mongoose.model('Hour', hourSchema);
It seems you are fetching the document into memory and re-setting the hour field to 0, better you can run an update query into the database itself.
On top require mongoose -
const mongoose = require('mongoose');
Below is clearHours method refactored.
exports.clearHours = async (req, res, next) => {
try {
const query = {
user: mongoose.Types.ObjectId(req.body.userId)
};
const update = {
$set: {
hours: 0
}
};
await Hour.update(query, update).exec();
res.status(200).json({message: 'Working hours have been successfully updated.'});
} catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};
I am trying to execute a callback after calling .findByIdAndDelete. Which actually does delete my item in the mongodb database, but the callback does not execute.
I've tried several solutions from other posts, but to no avail. How can I fix this?
Here's my code:
Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BoardSchema = new Schema({
name: String,
date: {
type: Date,
default: Date.now
}
}, { collection: 'boards' });
module.exports = Board = mongoose.model('board', BoardSchema);
Method Call
router.delete('/delete-board', (req, res) => {
console.log(req.body); // This does print out
var id = req.body.id;
Board.findByIdAndDelete(id, (err, board) => {
if (err) throw err;
console.log('stupid'); // This doesn't print out
return res.send({
message: 'Board has been deleted',
board: board
});
});
})
Check if req.body,id is valid id of any element in your database. If it isn't valid, your program won't execute callback, because it'll be not able to delete any element.
I am new to MongoDB. I created 4 collections & they are connected with each other. (I am using node.js to write it)
Here, it's my question. How can I delete all records at once? Is there something like deep level population?
This one holds all models.
const DataModel = mongoose.Schema({
_id: { type: mongoose.Schema.Types.ObjectId, ref: 'User', require: true},
order: { type: mongoose.Schema.Types.ObjectId, ref: 'Order', require: true},
});
User model
const userSchema = mongoose.Schema({//other stuff});
Order model
const orderSchema = mongoose.Schema({
product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
//other stuff
});
Product model
const productSchema = mongoose.Schema({//other stuff});
I can delete the entry with these code from the database, but the other entries still there
exports.delete_data = (req, res, next) => {
const id = req.params.userId;
userDataModel.deleteOne({_id: id})
.exec()
.then(docs => {
res.status(200).json({
message: 'Record Deleted',
request: {
type: 'POST'
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
Update: However, I wonder, Could I call other defined delete functions for order, product inside delete_data
As #Geert-Jan suggest, cascade delete is my solution. The link that geert-jan gave solve my problem. However, I wonder, Could I call other defined delete functions for order, product inside delete_data
i did this and it could be good for someone who wants to delete documents in cascade linked to any field of a model.
async blackHole() {
try {
const rtn = new ApiResponse<any>();
const userId = id;
const accountId = mongoose.Types.ObjectId(id);
var CollectionNames: any[] = [];
mongoose.connection.db.listCollections().toArray(function (err, collections) {
CollectionNames = collections.map(c => c.name);
CollectionNames.forEach((element: any) => {
mongoose.connection.db.collection(element).deleteMany({ "account": accountId });
});
});
const accountController = new AccountController(this.wsParams);
await accountController.delete(id)
await super.delete(userId);
return rtn;
} catch (error: any) {
const rtn = new ApiResponse<any>();
rtn.message = error;
rtn.success = false;
rtn.status = 422;
return rtn;
}
}
I hope you can use it :D
I am using mongoose to handle my schemas, with MongoDB, but when trying to save a new entry to a collection the save() method appears to be stuck, neither the then() method or the catch() method of the promise appear to be called.
Does anyone have any ideas?
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');
const config = require('./config');
const UserSchema = new Schema({
email: { type: String, required: true, index: { unique: true } },
name: { type: String, required: false },
password: { type: String, required: true }
});
const User = mongoose.model('User', UserSchema);
console.log('config.database.url', config.database.url);
mongoose.Promise = global.Promise;
return mongoose.createConnection(config.database.url, {
useMongoClient: true
})
.then((connection) => {
const user = new User({
email: 'someuser#somedomain.com',
password: 'xxxxx'
});
const prom = user.save();
// Displays: 'promise: Promise { <pending> }'
console.log('promise:', prom);
return prom
.then((result) => {
// Don't see this output
console.log('result:', result);
})
.catch((error) => {
// Don't see this output either
console.log('error:', error);
});
})
.catch((error) => {
console.log(error);
});
Environment: nodejs 8.9.0, node modules: Mongoose 4.13.6, mongodb 2.2.33
A little more experimenting and it would appear that I need to ensure the model is tied to the connection, such that:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');
const config = require('./config');
const UserSchema = new Schema({
email: { type: String, required: true, index: { unique: true } },
name: { type: String, required: false },
password: { type: String, required: true }
});
let User;
console.log('config.database.url', config.database.url);
mongoose.Promise = global.Promise;
return mongoose.createConnection(config.database.url, {
useMongoClient: true
})
.then((connection) => {
// associate model with connection
User = connection.model('User', UserSchema);
const user = new User({
email: 'someuser#somedomain.com',
password: 'xxxxx'
});
const prom = user.save();
// Displays: 'promise: Promise { <pending> }'
console.log('promise:', prom);
return prom
.then((result) => {
// Don't see this output
console.log('result:', result);
})
.catch((error) => {
// Don't see this output either
console.log('error:', error);
});
})
.catch((error) => {
console.log(error);
});
Alternatively we should use the connect() method that will work with the model associated via mongoose.model.
For createConnection() can be used to create multiple connections, so using a 'global' model is not supported, from what I can tell.
Saying all this it would be nice if save() didn't simply block.
Note: In researching a refinement to my answer I came across the following: Queries hang when using mongoose.createConnection() vs mongoose.connect()