MongoDb delete documents by passing user id - node.js

I am new to node and mongo db. I have a list of users with delete link in each row.I am trying to delete a user with its _id. However its not working.
Here is my router code.
router.get('/delete/:id', function (req,res) {
const ObjectId = require('mongodb').ObjectID;
var id = req.params.id;
console.log(id);
db.collection('users').deleteOne({ _id: ObjectId(req.params.id) }, function(err, res) {
if (err) {
throw err;
} else {
return res.redirect('/');
}
});
});
Here is my view, on clicking this link I am getting the _id in my url as this : http://localhost:3000/delete/4428439e14e3343ba4ac31c1
<td>Delete</td>
console.log(id) gives me 4428439e14e3343ba4ac31c1
But it throws me the below error
Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID

Try this, you don't need to create ObjectID if the string is a valid ObjectID
For prevention, you can use a function like below to test if valid ObjectID is passed or not
function validateObjectId (id) {
if (ObjectId.isValid(id)) {
const obj = new ObjectId(id);
if (obj == id) {
return true;
}
}
return false;
},
if(!validateObjectId(req.params.id))
return res.send({'error':'Invalid ObjectID Passed',id:req.params.id});
db.collection('users').deleteOne({ _id: ObjectId(req.params.id) }, function(err, res)
{
if (err) {
throw err;
} else {
return res.redirect('/');
}
});
Also remove extra space from here
<td>Delete</td>

You need to create a instance of ObjectId using new. Currently, you are passing the ObjectId directly so you are getting that error.
db.collection('users').deleteOne({_id: new ObjectId(req.params.id)}, function(err, res) {
if (err) {
throw err;
} else {
return res.redirect('/');
}
});

you can use findByIdAndRemove
router.get('/delete/:id', function (req,res) {
var id = req.params.id;
db.collection('users').findByIdAndRemove( id , function(err, res) {
if (err) {
throw err;
} else {
return res.redirect('/');
}
});
});

Maybe you can try this code below:
router.get("/delete/:id", function(req, res) {
const ObjectId = require("mongodb").ObjectId;
var { id } = req.params;
console.log(id);
db.collection("users").findOneAndDelete({ _id: ObjectId(id) }, function(
error,
response
) {
if (error) {
throw err;
} else {
return res.redirect("/");
}
});
});
Updated:
Try looking at your code. There's confusing code, you use 2 times res. One is res from express and the other isres when it succeeds in removing at mongodb.
So, the res.redirect ('/') that you use in your mongodb function is res from mongodb, notres from express.
Try replacing {err, res} with {error, response}.
I hope it can help you.

Related

CastError: Cast to ObjectId failed for value " 60f0d02f36ee6f2e505369e8" (type string) at path "_id" for model "collection"

app.get("/posts/:postId", function (req, res) {
let requestedPostId = req.params.postId;
Post.findById(requestedPostId, function (err, post) {
if (!err) {
res.render("post", { postTitle:post.title, postBody:post.content });
} else {
console.log(err);
}
});
});
This is the error I'm getting:
When I tried putting the existing _id of the document from the database in '''requestedPostId variable''' , then the code is working fine and the page gets loaded perfectly.
I mean to say that the database is not able to fetch data due to some casting error of objectId.
Can someone help?
Thanks in advance.
There's a Space in the ID being added, You can remove it, or add the trim function before doing the update.
app.get("/posts/:postId", function (req, res) {
let requestedPostId = (req.params.postId).trim();
Post.findById(requestedPostId, function (err, post) {
if (!err) {
res.render("post", { postTitle:post.title, postBody:post.content });
} else {
console.log(err);
}
});
});

RESTful API singular route with a single object to retrive and update (options parameters)

Hi i'm stucked trying to create a route in the RESTful API server in express.
I've configured other routes and now i need to configure an ('/options) or ('/profile') singular route where there is only one object to retrive and update.
Basically i need to do the same of the json-server module in the Singular routes section.
So when i visit the /options endpoint i got the predefined object with this schema
{
tax: Number,
inps: Number,
ritenuta: Number,
banca: {
nome: String,
iban: String
}
}
to update.
Here's my actual routes for /options:
var Option = require('../models/option');
var express = require('express');
var router = express.Router();
router.route('/options')
.get(function(req, res) {
Option.find(function(err, options) {
if (err) {
return res.send(err);
}
res.json(options);
});
})
.post(function(req, res) {
var option = new Option(req.body);
option.save(function(err) {
if (err) {
return res.send(err);
}
res.send({message: 'Option Added'});
});
});
// Save an option
router.route('/options/:id').put(function(req, res) {
Option.findOne({ _id: req.params.id}, function(err, option) {
if (err) {
return res.send(err);
}
for (prop in req.body) {
option[prop] = req.body[prop];
}
option.save(function(err) {
if (error) {
return res.send(err);
}
res.json({message: 'Option updated!'})
});
});
});
// Retrive an option
router.route('/options/:id').get(function(req, res) {
Option.findOne({ _id: req.params.id }, function(err, option) {
if (err) {
return res.send(error);
}
res.json(option);
});
});
// Delete an option
router.route('/options/:id').delete(function(req, res) {
Option.remove({ _id: req.params.id}, function(err, option) {
if (err) {
return res.send(err);
}
res.json({message: 'Option deleted!'});
});
});
module.exports = router;
but it's much complicated. It should be simpler. In fact, in this case i need to get all the options, get the id of options[0] and make a call with the id as params to retrive the object and update.
Any suggestions please?

Mongoose find not working with ObjectId

I have one schema defined in userref.js
module.exports = (function userref() {
var Schema = mongoose.Schema;
var newSchema= new Schema([{
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
index: true
},
value: { type: Number }
}]);
var results = mongoose.model('UserRef', newSchema);
return results;
})();
I have inserted some data and when I try to fetch some data I am getting proper values from mongodb console
db.getCollection('userrefs').find({'userId':ObjectId('57a48fa57429b91000e224a6')})
It returns properly some data
Now issue is that when I try to fetch some data in code by giving objectId I am getting empty array. In below function userrefs is returned as empty array
//req.params.userId=57a48fa57429b91000e224a6
var UserRef = require('../userref.js');
this.getuserref = function (req, res, next) {
try {
var o_userId =mongoose.Types.ObjectId(req.params.userId);
var query = { userId: o_userId };
var projection = '_id userId value';
UserRef.find(query, projection, function (err, usrrefs) {
if (err) return next(err);
res.send(usrrefs);
console.log("userref fetched Properly");
});
} catch (err) {
console.log('Error While Fetching ' + err);
return next(err);
}
};
Also when I debug code I can see o_userId as objectId with id value as some junk character
o_userId: ObjectID
_bsontype: "ObjectID"
id: "W¤¥t)¹â$¦"
Try this:
try {
var o_userId =mongoose.Types.ObjectId(req.params.userId);
var query = { userId: o_userId };
var projection = '_id $.userId $.value';
UserRef.find(query, projection, function (err, usrrefs) {
if (err) return next(err);
res.send(usrrefs);
console.log("userref fetched Properly");
});
} catch (err) {
console.log('Error While Fetching ' + err);
return next(err);
}
Add the export like this
module.exports.modelname= mongoose.model('userrefs', nameofschema, 'userrefs');
var z = require('../userref.js');
var UserRef = z.modelname;
Now call using UserRef.
Just simply try this man.
Model.find({ 'userId': objectidvariable}, '_id userid etc', function (err, docs) {
// docs is an array
});
Reference sample copied from their official doc.

MongoDB objectID stranger Error

Using a MEAN Stack deployment on Heroku I am able to GET and DELETE Documents with mongoDB's findOne and deleteOne functions. However when I try to PUT a document with the mongoDB updateOne/update function, I receive this error (server side) :
The _id field cannot be changed from {_id: ObjectId('56d4d71191fdc81100974d0b')} to {_id: "56d4d71191fdc81100974d0b"}.
Seems strange because I am using the same method in my server code for updateOne as in findOne (again, findOne works fine):
app.get("/contacts/:id", function(req, res) {
db.collection(CONTACTS_COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, function(err, doc) {
if (err) {
handleError(err.message, "Failed to get contact");
} else {
res.status(200).json(doc);
}
});
});
app.put("/contacts/:id", function(req, res) {
var updateDoc = req.body;
db.collection(CONTACTS_COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function(err, doc) {
if (err) {
handleError(err.message, "Failed to update contact");
} else {
res.status(204).end();
}
});
});
Any suggestions?
I think you have problem at var updateDoc = req.body
As req.body contains id field and you are searching from object to update by that id, mongodb thinks you are trying to update
id field too which is not allowed.
One solution is to remove id field from your updateDoc object.
e.g.
delete updateDoc._id;
now try again and see if it works.
Your final function should look like
app.put("/contacts/:id", function(req, res) {
var updateDoc = req.body;
delete updateDoc.id;
db.collection(CONTACTS_COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function(err, doc) {
if (err) {
handleError(err.message, "Failed to update contact");
} else {
res.status(204).end();
}
});
});

NodeJS / Mongoose Filter JSON

I am building a JSON API with ExpressJS, NodeJS and Mongoose:
Input -> id:
app.get('/folder/:id', function (req, res){
return Cars.find({reference: req.params.id}, function (err, product) {
if (!err) {
console.log(product);
return res.send(product);
} else {
return console.log(err);
}
});
});
It shows well the JSON:
[{"_id":"B443U433","date":"2014-08-12","reference":"azerty","file":"087601.png","
....:.
{"_id":"HGF6789","date":"2013-09-11","reference":"azerty","file":"5678.pnf","
...
I just want to display the _id in the JSON, so it is good when I have lots of data.
How I can do that? Something like a filter?
You can chain calls to select and lean to retrieve just the fields you want from the docs you're querying:
app.get('/folder/:id', function (req, res){
return Cars.find({reference: req.params.id}).select('_id').lean().exec(
function (err, product) {
if (!err) {
console.log(product);
return res.send(product);
} else {
return console.log(err);
}
});
});
You would have to iterate over your "products" object to obtain the ids
Something like this:
(Disclaimer: I haven't tested this)
app.get('/folder/:id', function (req, res){
return Cars.find({reference: req.params.id}, function (err, product) {
if (!err) {
console.log(product);
var ids = new Array();
for(var i = 0; i < product.length; i++){
ids.push(product[i]._id);
}
return res.send(JSON.stringify(ids));
} else {
return console.log(err);
}
});
});
--Edit
Also, "products" may already be a JSON string. You may want to parse it before looping.
product = JSON.parse(product);
Other answers are true but I think it's better to limit data in mongoose like this :(it's same as mongo shell commands)
app.get('/folder/:id', function (req, res){
Cars.find({reference: req.params.id} ,{ _id : true } ,function (err, product) {
if (!err) {
console.log(product);
} else {
console.log(err);
}
});
});

Resources