My document is not getting deleted in mongodb in nodejs - node.js

My document is not getting deleted from the collections. Iam also not getting any error. The http transaction is perfectly fine.
// Node Module dependencies
var express = require('express');
var router = express.Router();
// Local Module dependencies
var common = require('./common.js');
//var request = require('request');
var db =common.conn;
var Question = require('../model/questions');
router.route('/postquestion')
.post(function (req, res) {
var item = new Question(req.body);
//console.log(item);
//=======calling postdata method=====//
postQuestion(item, function (result) {
res.json(result);
});
});
router.route('/deletequestion')
.delete(function (req, res) {
console.log(req.body._id);
Question.collection.deleteOne({_id:req.body._id},function(err,question){
if(err) throw err;
console.log('the document is deleted')
res.send(question);
});
})
function postQuestion(item, fn) {
item.save(function (err) {
if (err) console.log(err);
fn(item);
});
}
module.exports = router;
postquestion function is working perfectly fine and the database is getting updated. When i use postman for raising a delete request and send the below json.
{
"_id": "57bc442c4925180b067f075b"
}
iam getting a response like the below.
{
"ok": 1,
"n": 0
}
When i check the database in robomongo i see the document is not deleted. Am i missing something to be done. Is there anything else to be done.....!

MongoDB uses ObjectID to index document.
If you want to delete object using Mongo ID you have to instanciate an ObjectID.
https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/
var ObjectID = require('mongodb').ObjectID;
router.route('/deletequestion')
.delete(function (req, res) {
console.log(req.body._id);
const _id = new ObjectID(req.body._id);
Question.collection.deleteOne({_id:_id},function(err,question){
if(err) throw err;
console.log('the document is deleted')
res.send(question);
});
})

if nothing works, try the following...
app.delete("/api/posts/:id",(req,res,next)=>
{
Post.deleteOne({_id: req.param.id})
.then(result=>{
console.log(result);
});
//console.log('Post Deleted on node JS');
res.status(200).json({message: 'Delete'});
});

If you are using MongooseJS, you just need to do Question.deleteOne({...}), you don't need to do theQuestion.collection...` thing. Unless you have stuff wired up differently in your Model

Related

mongoose creating null document after using module export in express

I was recently using a function to upload files to a mongodb database successfully. However after moving those functions into a file (to clean up) and exporting that file then requiring it in my route, the database now creates documents with only null values like so:
_id:ObjectId("xxxxxxxxxxxxxxx")
name:null,
value:null,
image:null,
desc:null
I don't know what might be causing this, I am logging the argument object that i'm trying to insert from inside the function 'insertProducts' and the item.name is not null. Sorry I'm new to mongodb :/
maybe someone can point me in the right direction?
CRUD.js
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const removeProducts = function(req,res){
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
let users = db.collection('users');
try{
products.remove({ _id: req.body.id }, function(err) {
if (!err) {
console.log('removed item')
}
});
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/addItems')
})
}
const insertProducts = function(item,res){
console.log("item name",item.name)
MongoClient.connect('mongodb://localhost', (err, client) => {
if (err) {
throw err;
}
let db = client.db('account-app');
let products = db.collection('products');
try{
products.insertOne(item)
console.log('item inserted')
}
catch(err){
console.log('Error while inserting', err)
}
client.close()
res.redirect('/admin/addItems')
})
}
module.exports={removeProducts: removeProducts, insertProducts: insertProducts}
my admin route that requires the crud functions
const crudOps = require('../utils/admin/CRUD') //require CRUD functions
// Adding new items
// --------------------------------------------------
router.post('/addNewItems', (req, res, next) => {
console.log(req.body.name)
let item = {
name:req.body.name,
file: binary(req.files.image.data),
value: req.body.value,
desc: req.body.desc
}
crudOps.insertProducts(item, res)
});
That connection URL looks wrong. Generally, it has the format:
mongodb://localhost:27017/mydatabase
Try replacing the connection string with the appropriate one for your database and see if that works. Also, the docs normally have insertOne statements like this so maybe that is the issue?
products.insertOne(item, function(err, r) {
console.log('item inserted')
res.redirect('/admin/addItems')
db.close();
});

How to get the collection name from called API

I'm working on a node js application with mongoDB. Where I need help to get the collection name when I call the API for that collection.I want to use it in Middleware functions.
I got the method of that called API from this.
const getmethod = req.method;
You need to first create Middleware and get and bind the collection list with the request as follows.
const mongoose = require('mongoose');
const connection = mongoose.connect('mongodb://localhost:27017');
const getmethod = req.method;
app.use(function(req, res, next) {
connection.on('open', function () {
connection.db.listCollections().toArray(function (err, names) {
if (err) {
console.log(err);
//Error in get collection
req.collectionName = '';
mongoose.connection.close();
next();
} else {
console.log(names);
if(names.includes(getmethod)){
req.collectionName = getmethod;
}else{
//there is no collection exist for this method
req.collectionName = '';
}
mongoose.connection.close();
next();
}
});
});
});

How to pass data from model to router in Node.js

I'm new to Node.js and am trying to pass some data from my DB model back to the router but I'm unable to find a solution. I have the following route file that makes a call to model:
Route file:
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password);
res.sendStatus(200);
});
Model file:
var db = require('../db.js');
module.exports.checkPassword = function(cust_id, password) {
var sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
result = res[0].Password;
if (err) throw err
});
};
My question is: how could I pass the queried result Password back to my Route file so that I can do this:
console.log('Password is', result);
I appreciate any help on this.
I'd use a promise
Model file
module.exports.checkPassword = function(cust_id, password) {
return new Promise(function(resolve, reject) {
const sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
if (err) return reject(err)
result = res[0].Password;
return resolve(result);
});
});
};
Route file
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password)
.then((result) => {
// DO: something with result
res.status(200).send();
})
.catch(console.log); // TODO: Handle errors
});
With async/await
router.post('/', async function(req, res) {
try {
const result = await customers.checkPassword(req.body.cust_id, req.body.password)
// DO: something with the result
} catch (e) {
console.log(e); // TODO: handle errors
} finally {
res.status(200).send();
}
});
I assume console.log('Password is', result); is just for test prupose, obviously you should never log a password! Also I suggest to move the callbabck of the routes do a different module, to improve code redability.
You might also find useful promise-module module on npm, basically a promise wrapper around mysql.
You can delegate the credential control to another function in your DB file where you can decide on what kind of data you want to return on success and failure to find such data. Then you can access it from where you are calling it.

Remove a MongoDB Document using Express JS

I have careted an application that interacts with MongoDb using NodeJS (Express JS). I am trying to remove a document using the "_id" (the one generated by MongoDB). The following piece of code just logs "Deleted Successfully", but does not actuall remove the record:
app.post('/TaskDone', function (req, res) {
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db;
var server = new Server('localhost', 27017, { auto_reconnect: true });
var database = new Db('pending-list-2', server);
database.open(function (err, db) {
if (!err) {
console.log("Connected for Deletion");
db.collection('tasks', function (err, coll) {
var str = "{_id :"+"ObjectId(" + "\"" + req.body + "\"" + ")" + "}";
console.log(str);
coll.remove(str, function (err) {
if (err) console.log(err);
else console.log("Deleted successfully");
}
);
});
}
});
});
If I use the MongoDB client and just run db.tasks.remove({_id:ObjectID("idhere")}) , it works. Is there something wrong with the express js code that I have written. I have tried a lot of things but nothing seems to work.
You must create an ObjectID from the mongodb library:
Also this is expected that you do not have any error. The remove() is executed, but the filter is probably invalid.
So you will have to write something like like:
var mongodb = require('mongodb');
...
...
collection.remove(
{_id: new mongodb.ObjectID( req.body) },
function (err, result){
//check result to see how many document are deleted
});
Try as below:
var id = {
_id: req.body.id
};
var collection = db.collection("tableName");
collection.remove(id, function(err, records){
if(err){
console.log("Error" + err);
}
else{
console.log("Omega Job Removed");
}
});

Mongoose model.save() not persisting to database on update

I am developing a mongoose / node.js / express app.
in my routes I am using express' app.param() method to get my model instance into the request - instead of fetching it in each controller action.
i got show and create actions working in my controller - however I am stuck implementing the update action.
here is my relevant controller code:
// mymodel-controller.js
var mongoose = require('mongoose')
var MyModel = mongoose.model('MyModel');
var utils = require('../../lib/utils');
"use strict";
exports.update = function (req, res, next) {
var mymodel = req.mymodel;
mymodel.set(req.body);
mymodel.slug = utils.convertToSlug(req.body.title);
mymodel.save(function(err, doc) {
if (!err) {
console.log('update successful');
// here i see the correctly updated model in the console, however the db is not updated
console.dir(doc);
return res.redirect('/mymodels/' + mymodel.slug);
} else {
console.error('update error', err);
return res.render('mymodels/edit', {
title: 'Edit Model',
model: mymodel,
errors: err.errors
});
}
});
}
The strange thing is, the mongoose save goes through successfully, I don't get any error.
I see 'update successful' and the correctly updated model printed on the console, but not persisted in the database.
I tried also fetching the model manually before updating and saving it, instead of using app.param(..) but I had the same effect.
Any idea what I am missing here?
update
this is the code where I set the req.mymodel - part of a longer routes file.
In my show actions e.g. I also use req.mymodel to display it and it works fine so far.
/**
* mymodel ROUTES
*/
app.param('mymodel', function(req, res, next, id){
MyModel.findOne({ 'slug': id }, function(err, mymodel) {
if (err) {
next(err);
} else if (mymodel) {
req.mymodel = mymodel;
next();
} else {
res.status(404).render('404', {title: "Not found", errorMessage: "The requested mymodel was not found."});
}
});
});
app.get('/mymodels', mymodelsController.index);
app.get('/mymodels/new', mymodelsController.new);
app.post('/mymodels', mymodelsController.create);
app.get('/mymodels/:mymodel', mymodelsController.show);
app.get('/mymodels/:mymodel/edit', mymodelsController.edit);
app.put('/mymodels/:mymodel', mymodelsController.update); // that's the one not working with the code above
app.del('/mymodels/:mymodel', mymodelsController.destroy);
update2
This code, on the other hand, works in my controller and updates the database (I'd much prefer using instance.save() though)
exports.update = function (req, res, next) {
var mymodel = req.param('mymodel');
var query = { slug: mymodel };
var update = {};
update.title = req.param('title');
update.body = req.param('body');
update.points = req.param('points');
update.location = req.param('location');
update.slug = utils.convertToSlug(req.param('title'));
MyModel.update(query, update, function (err, numAffected) {
if (err) return next(err);
if (0 === numAffected) {
return next(new Error('no model to modify'), null);
}
res.redirect('/mymodels/' + update.slug);
});
}
The problem was indeed the way I set the req.param value in my routes.
Instead of doing this in my routes file:
app.param('mymodel', function(req, res, next, id){
MyModel.findOne({ 'slug': id }, function(err, mymodel) {
if (err) {
next(err);
} else if (mymodel) {
req.mymodel = mymodel;
next();
} else {
res.status(404).render('404', {title: "Not found", errorMessage: "The requested mymodel was not found."});
}
});
});
I had to declare a controller action that loads the instance each time, like
app.param('mymodel', mymodelController.load);
which pretty much looks like in this example.

Resources