mongoose findByIdAndRemove() strange behavior - node.js

im working with mongoose and when i tried using query like .findByIdAndRemove()
it deleted the content but not remove the product from the database
it just turn it to Null
like
{"_id":"5d67502aaffb3729a0e24904","name":null,"image":null,"price":null,"desc":null,"__v":0}
Form
<form action='/product/<%=product._id%>' method="POST">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
//Route
router.post('/product/:productId',productController.deleteProduct)
//controller
//delete product
exports.deleteProduct = (req, res, next)=>{
const prodId = req.params.productId
Product.findByIdAndRemove(prodId)
.then(() =>{
console.log('has been deleted')
res.redirect('/product')
})
.catch(err=>{console.log(err)})
}

Could please try below delete script.
It's removing by one document using id
Product.remove({_id : new mongoose.Types.ObjectId(prodId)}, (err, result) => {
if(err) console.log(err);
else console.log(result)
})
It's removing document by _id
Product.findByIdAndRemove(prodId, (err, result) => {
if(err) console.log(err);
else console.log(result)
})
It's removing by one document
Product.remove({name: 'yourName'}, (err, result) => {
if(err) console.log(err);
else console.log(result)
})
or another option
Product.deleteOne({ name: 'Eddard Stark' }, callback);
In router
router.delete('/product/:productId',productController.deleteProduct)
In the front end, you call delete API. If the interest you can learn MEARN Stack CRUD operation in GitHub link

Related

Send multiple collections to one ejs file using mongodb and nodejs

app.get('/index', function(req, res){
Activities.find({}, function(err, activity){
if(err){
console.log(err);
}else{
res.render('index', {activities:activity});
}
});
Upcoming.find({}, function(err, upcomingActivity){
if(err){
console.log(err);
}else{
res.render('index', {upcoming:upcomingActivity});
}
});
});
I just want to get data of multiple collections and then pass it to index.ejs file so that i can use these data there.
I know using res.render() multiple times won't work but i have tried many things like saving founded data to variable , creating an object of these etc. But nothing
worked.
In your get response you should render only once the index page passing the parameters all together.
app.get('/index', function(req, res){
Activities.find({}, function(err, activity){
if(err){
console.log(err);
}else{
Upcoming.find({}, function(err, upcomingActivity){
if(err){
console.log(err);
}else{
res.render('index', {activity:activity, upcoming:upcomingActivity,});
}
});
}
});
});
It will work this way, since you have only a few collections but other way to do so is passing it as a global object and then rendering it.
Use then to render asynchronously
app.get('/index', (req,res) => {
Activities.find().then(activity => {
Upcoming.find().then(upcomingActivity => {
res.render('index', {Activities: activity, Upcoming: upcomingActivity})
}).catch(err => console.log(err))
}).catch(err => console.log(err))
})

Deleting the model data through lodash and save() not persisting model in mongodb

I am trying to remove one object from the User collection like this
router.post('/accept-trades', function (req, res, next) {
const {senderName, receiverName, senderId} = req.body;
const user = req.user;
console.log(senderName, receiverName);
if (senderName) {
User.findOne({ name: senderName })
.then(sender => {
_.remove(user.receivedTradeRequest, {username: senderName});
_.remove(sender.sentTradeRequest, {username: receiverName});
console.log('user.receivedTradeRequest', user.receivedTradeRequest);
console.log('\n\nuser.sentTradeRequest', user.sentTradeRequest);
async.parallel([
function (cb) {
user.save()
.then(isSave => {
cb(null, true);
})
.catch(err => {
cb(err, null);
});
},
function (cb) {
sender.save()
.then(isSave => {
cb(null, true);
})
.catch(err => {
cb(err, null);
});
}
], (err, results) => {
if (err) {
return res.status(500).json({
message: 'Error: Trade is invalid as Card is already traded!',
});
}
res.send('done');
//res.redirect('/trade');
});
})
.catch(err => {
throw err;
});
} else {
return res.status(500).json({
message: 'Only accessible to logged in users!',
});
}
});
Here, user is accessed by req.user (i'm using passport).
When i log the user after removal, user.receivedTradeRequest and sender.sentTradeRequest printing empty array which is the correct behaviour.
But when i see the mongodb the array still present for the username.
Could you please suggest what is wrong with the code ?
PS: I know about the mongodb $pull for removal. I am doing some other computation on the user data so had to do with above approach.
I was able to solve it by re-assigning the array after removing the element. Used _.filter instead of _.remove solves the problem.
One thing i don;t understand is the lodash _.remove update the original array after deletion but that clearly is not the case here.

Mongodb and Express deleting an item from _id

I'm new to Express and databases. I'm trying to create a simple CRUD todo list by following several tutorials using Mongo DB (not Mongoose), Express, Node, and Handlebars.
I can create items from an input form and have them successfully save to the Mongo database and the page. I can't figure out how to delete each item based on a button click both on the page and from the database. Ideally, I want to target them based on the _id that Mongo creates.
I think the issue might be having something to do with the way I'm trying to select each item. Any suggestions or easier ways to implement this would be great!
Here is my code for Express:
// Connecting Mongo DB
MongoClient.connect(url, (err, client) => {
if (err) return console.log(err)
db = client.db('todoitems')
})
// Save items to DB from form
app.post('/items', (req, res) => {
db.collection('items').save(req.body, (err, result) => {
if (err) return console.log(err)
console.log(req.body, {_id: req.body._id})
res.redirect('/')
})
})
// Delete item on click from DB
app.delete('/items/:id', (req, res) => {
db.collection('items').remove({_id: req.body.id}, (err, result) => {
if (err) return console.log(err)
console.log(req.body)
res.redirect('/')
})
})
// Get items from DB to page
app.get('/', (req, res) => {
db.collection('items').find().toArray((err, result) => {
if (err) return console.log(err)
res.render('index', {
layout: false,
items: result
});
})
})
And here is my code from the Handlebars file:
<form action="/items" method="POST">
<input type="text" placeholder="item" name="item">
<input type="hidden" id="date" name="date" value="CurrentDate">
</form>
<ul>
{{#each items}}
<li>
<span>{{item}} |</span>
<span>{{date}}</span>
<button id={{_id}}>x</button>
</li>
{{/each}}
</ul>
If you are removing by _id, you need to pass an ObjectID(id) not a "string" id, something like:
remove({_id: mongodb.ObjectID( req.params.id)} ...
So, your code should be like:
app.delete('/items/:id', (req, res) => {
db.collection('items').remove({_id: mongodb.ObjectID( req.params.id)}, (err, result) => {
if (err) return console.log(err)
console.log(req.body)
res.redirect('/')
})
})

GET request for specific id returning null

I'm attempting to build a simple CRUD application using express and mongodb. My GET request for all database entries is working and my POST request is working but I can't seem to figure out the problem with my GET request for individual entries.
Server.js GET request:
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: id}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
When I type 'url/api/593555074696601afa192d7f' which is an ID I know exists the console.log is returning null, I'm not sure if I'm doing something wrong?
You should pass ObjectID instance in the query.
let ObjectID = require("mongodb").ObjectID;
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: ObjectID(id)}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
Give Mongoose a try. It might be of help if your models get complex.

find all documents using mongoose

Im trying to find all documents in a DB using mongoose but I cant do it
I want to do it this way but I don't know what's wrong with it
app.get('/users', function (req, res){
User.find({}, 'name', function(err, user){
if(err){
console.log(err);
}else{
res.render('user-list', {
name : user.name
});
console.log('retrieved list of names' + user.name);
}
})
})
When I use User.findOne({}, 'name', function(err, user){.. I get back the first doc which is what I would expect. Please explain why the code above is not allowing me to get all documents. I feel like I'm using it the right way as show in the mongoose doc
Edit
thanks for help guys
i did like this:
app.get('/users', function (req, res){
User.find({}, 'name', function(err, users){
if(err){
console.log(err);
}else{
res.render('user-list', {
name : users.map(function(doc){
return doc.name + "<br>"
})
});
console.log('retrieved list of names' + users.name);
}
})
})
can some one please help me with getting each name on a new line the "<br>" shows up on the page but it doesn't make a new line "<br>,Joe<br>,mike<br>"
Jade:
extend layout
block content
p list of users #{name}
app.get('/users', function (req, res){
User.find({}, 'name', function(err, users){
if(err){
console.log(err);
} else{
res.render('user-list', users);
console.log('retrieved list of names', users.length, users[0].name);
}
})
});
As said in the comments, find can find many objects, so it returns an array as contrasted with findOne that returns a single object. Adjust for that as above and you should be back on track.
app.get(`/users`, async (req,res)=>{
try{
const users = await User.find({}).exec()
users && res.render('user-list',users)
}catch(error){
res.status(500).json({error})
}
})
//OR
app.get(`/users`, async (req,res)=>{
try{
const users = await User.find({}).exec()
const list = new Array()
for(let row of users){
list.push(`${users.name}<br>`)
}
list ? res.status(200).send(list) : res.status(200).json({message: 'Users list is empty'})
}catch(error){
res.status(500).json({error})
}
})
In second example you send to client a text line!!!

Resources