removing multiple document's references using mongoose - mongodb

I'm currently trying to remove multiple documents references (objectId) when i'm removing those documents.
So this is my code to remove multiple documents and their references:
Comment.find({parentCommentId: req.params.id}).stream()
.on('data', function (comment) {
comment.remove(function (err, result) {
if (err){
console.log(err)
}
console.log(result);
})
})
.on('error', function(err){
// handle error
})
.on('end', function(){
res.status(200).json({
title: 'Comments deleted'
});
});
(this is the middleware i use)
schema.post('remove', function (comment) {
Project.findById(comment.project, function (err, project) {
if(err){
console.log('error : '+ err)
}
project.comments.pull(comment);
project.save();
});
User.findById(comment.user, function (err, user) {
if(err){
console.log('error : '+ err)
}
user.comments.pull(comment);
user.save();
});
});
At the moment i tried multiple things but i kinda got stuck: it removes all the documents i wanted but it always only removes the first document's reference and keeps the other ones.
at this point i don't really understand why.
Have a good day : )

Related

Store collection value to variable

I am having issues storing a value in mongodb to a variable to use within my webpage.
When the user fills out a form on my website, I am trying to figure out what the arrivalTrailer was when the user filled out the arrival form.
So far I have
function previousLoad(loadNumber, callback){
CheckCall.find({loadNumber: loadNumber}).sort({date: 'desc'}).limit(1), function(err, arrival){
if (err){
callback(err, null);
}
else {
callback(null, arrival[0]);
}
}};
previousLoad(loadNumber, function(err, arrival){
if (err){
console.log(err);
}
else{
arrivalTrailer = arrival;
console.log(arrival);
}
});
console.log(previousLoad.arrival);
console.log(arrivalTrailer);
Both output as undefined when I try to console.log the variables.
Thank you :D
Try this :
async function previousLoad(loadNumber) {
try {
let resp = await CheckCall.find({ loadNumber: loadNumber }).sort({ date: -1 }).limit(1)
return resp[0]
} catch (error) {
console.log('error ::', error)
throw new Error (error)
}
}
/** You can return response from previousLoad but to test it, Call it from here */
previousLoad(loadNumber).then(resp => { console.log('successfully found ::', resp)}).catch(err => { console.log('Error in DB Op ::', err)});

node-postgresql db connection deprecated

I am using node-v8.9.1-x64. & postgresql-10.1-2. I have tried running this code but its gives an error "code deprecated" and even tried some other ways. It still comes back with new errors
app.get('/', function(req, res) {
// PG connect -code deprecated
pg.connect(connect, function(err, client, done) {
if(err) {
return console.error('error fetching client from pool', err);
}
client.query('SELECT * FROM books', function(err, result) {
if(err) {
return console.error('error running query', err);
}
res.render('index', {books: result.rows});
done();
});
});
I went through the documentation but I am not getting it. Please somebody help me.

Reversed result in mongoose

I'm trying to get a list of all "Task" documents from my mongoDB in a reverse order, so latest added "Tasks" are first in the list.
Is there a smart way of doing that?
allTasks(){
return Task.find(function (err, allTasks) {
if (err) return console.error(err);
return allTasks;
})
}
UPDATE
Following code solves the problem:
allTasks(){
return Task.find().sort({created_at:-1}).exec(function (err, allTasks) {
if (err) return console.error(err);
con
return allTasks;})
}

Rollback Transaction for Multiple Models in Waterline ODM in Sails (For Mongo DB )

I am using Sails and Waterline ORM with Mongo Database .
I have two models User and Profile with One to One relationship.
Below is the code I've written for Transaction with Rollback logic. I think there can be a much better logic than this as the current logic is very clumsy.
Questions :
Does Waterline or Sails provide any functionality for Rollback purpose?
Is there any better way of doing this ?
User.create(newUser).then(function (data) {
var newProfile = {
displayName: data.name,
email: data.email,
user: data._id
}
return Profile.create(newProfile);
}).then(function (profileData) {
sails.log.info("Profile Data " + JSON.stringify(profileData));
// Update the user with Profile Info
User.update(newUser._id, {profile: profileData._id}).then(function (updatedUser) {
return updatedUser;
}, function (err) {
// TODO Rollback logic if the User Updation Fails
})
}, function (err) {
sails.log.error("Failed to Create Profile for the User . Deleting the created User");
var criteria = {
email: data.email
}
User.destroy(criteria).then(function (user) {
sails.log.error("Deleted the Created User " + JSON.stringify(user));
throw new Error("ERROR CREATING User");
}, function (err) {
sails.log.error("ERROR DELETING USER");
throw new Error("ERROR DELETING USER", err);
})
});
To question 1 : no.
I would be tempted to do something like this:
async.waterfall([
function(callback){
User.create(newUser).then(function(data){
callback(null, data);
})
.catch(function(err){
callback(err, null, null); // don't need to rollback anything
})
},
function(data, callback){
Profile.create({
displayName: data.name,
email: data.email,
user: data._id
})
.then(function(profile){
callback(null, data, profile)
})
.create(function(err){
callback(err, data._id, null); // only need user's id
})
},
function(userData, profileData, callback){
User.update(userData._id, {profile: profileData._id})
.then(function(updatedUser){
callback(null, updatedUser);
})
.catch(function(err){
callback(err, userData._id, profileData._id); // can roll back both
})
}
], function(err, userData, profileData){
if(err) {
sails.log.error(err);
// do rollback, userData is user's ID, profileData is profile id
// if either one is undefined, then it doesn't exist
} else {
// userData is user object from the last update, return it!
}
})
I don't know if it is better, but it seems more readable, and it handles the errors for any of the three writing phases.

Node Express Trouble returning object to view from query

I'm trying to:
Pass user's ID to a model query, that should return the user record from mongo.
Render this user object to my view so I can use its fields.
I'm not quite sure what's going wrong - the query function finds the correct user and I can console.dir to see all the fields. When I try to return it to my view with res.render I get nothing:
Here's my route:
app.get('/account', function(req, res) {
res.render('account', {title: 'Your Account', username: req.user.name, user:account.check(req.user.id) });
});
And my query function:
exports.check = function(userId) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test');
collection.findOne({userId : userId}, function(err, user) {
if (err) throw err;
console.log("account.check logging found user to console: ");
console.dir(user);
return user;
});
});
}
Again, this shows the proper entry
Finally my view:
<h1>Account Page</h1>
<hr>
<p>Why, Hello, there <b> {{username}} </b> </p><br/>
<p>You came from {{user.provider}}</p>
<p>{{user.lastConnected}}</p>
Go Home ~ Log Out
Any held would be most appreciated!
The MongoDB findOne function is asynchronous (it takes a callback as an argument). This means that your check function also needs to be asynchronous and take a callback as an argument (or return a promise).
Then you should call res.render() inside the callback you pass to query on success.
app.get('/account', function(req, res) {
account.check(req.user.id, function(error, user) {
if (error) {
// do something smart like res.status(500).end()
return;
}
res.render('account', {title: 'Your Account', username: req.user.name, user:user });
}
});
And the check function should be something like:
exports.check = function(userId, callback) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) {
callback(err);
}
var collection = db.collection('test');
collection.findOne({userId : userId}, function(err, user) {
if(err) {
callback(err);
}
console.log("account.check logging found user to console: ");
console.dir(user);
callback(null, user);
});
});
}
Of course if you don't need to do any additional processing, you can just pass your the callback argument as the callback to collection.findOne(). I just kept it this way because it was closer to what you were doing initially.