Can't delete a document from Mongodb via Express route - javascript

I want to delete a Mongodb document by id, passing it to Express route.
In the console, I receive a message that says it is deleted.
GET /api/videolinks 304 94.792 ms - -
Removed id= 562b905f633288ac0d8b4567
DELETE /api/videolinks/562b905f633288ac0d8b4567 200 68.550 ms - 19743
But it is not.
> db.hyperlinks.find({"_id": ObjectId("562b905f633288ac0d8b4567")})
{ "_id" : ObjectId("562b905f633288ac0d8b4567"), "file" : "http://storage.akamai.com/get/b113/p/coub/simple/cw_file/79632d71313/9aedca2cd4d3094e75834/iphone_hellosergii_iphone.mp4" }
My Angularjs factory:
/*global angular*/
angular.module('myService', [])
// each function returns a promise object
.factory('Videolinks', ['$http',function($http) {
return {
get : function() {
return $http.get('/api/videolinks');
},
delete : function(id) {
return $http.delete('/api/videolinks/' + id);
}
};
}]);
My route.js
var path = require('path');
var Videolink = require('./models/mydb');
var mongodb = require('mongodb');
// Get links
function getLinks(res){
Videolink.find(function(err, hyperlinks) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err) {
res.send(err);
}
res.json(hyperlinks); // return all videos in JSON format
});
}
module.exports = function(app) {
// api ---------------------------------------------------------------------
// use mongoose to get all videos in the database
app.get('/api/videolinks', function(req, res) {
getLinks(res);
});
// delete a video
app.delete('/api/videolinks/:video_id', function(req, res) {
Videolink.remove({
_id : mongodb.ObjectID(req.params.video_id)
}, function(err) {
if (err) {
res.send(err);
}
console.log("Removed id= " + req.params.video_id);
getLinks(res);
});
});
// application -------------------------------------------------------------
app.get('*', function(res) {
res.sendFile('index.html', {root: path.join(__dirname, './public')}); // load the single view file
});
};
The app.get functionality works pretty well here.
What could be wrong with app.delete?
Here is my DB schema in models/mydb
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var db_schema = new Schema({
//text: String
_id: String,
source: String,
orig_page: String,
likes: Number,
title: String,
file: String,
video_mobile_res: String,
video_high_res_mutes_muted: String,
audio_high_res: String,
video_med_res_muted: String,
audio_med_res: String
}, {collection: 'hyperlinks'});
module.exports = mongoose.model('Videolink', db_schema);

Your particular problem is that you defined the _id field as a String in your schema:
var db_schema = new Schema({
_id: String,
...
Take that out and your code should work fine. You may have even uncovered a mongoose bug, since you are supposed to be able to specify the _id field type. Maybe some mongoose expert can tell us more.

Related

Node.js and mongoose update parameters

task.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var taskSchema = new Schema({
status: {type: String, default: 'TO-DO'},
contents: String,
createDate: {type: Date, default: Date.now},
author: {type:String, defafult:'Chris'}
});
module.exports = mongoose.model('Task', taskSchema);
task-controller.js
var Task = require('../models/task.js');
exports.update = function(req, res) {
Task.update({
contents : req.body.contents
}, {
status : req.body.status
}, function(err, numberAffected, raw) {
if (err) {
throw err;
}
console.log('The number of updated documents was %d', numberAffected);
console.log('The raw reponse from MongoDB was', raw);
});
res.redirect('/');
res.end();
};
At task-controller.js, You can see "numberAffected" and "raw" parameters.
However when I execute the code, the console displays
The number of updated documents was NaN
The raw reponse from MongoDB was undefined
So I searched the reference, but I can't find those kinds of parameters.
Are those parameters valid?
That is because Model.update returns a callback with only two parameters first parameter being err and second numAffected (which is Object not a number) as follows :
var Task = require('../models/task.js');
exports.update = function(req, res) {
Task.update({
contents : req.body.contents
}, {
status : req.body.status
}, function(err, numberAffected) {
//numberAffected is Object
if (err) {
throw err;
}
console.log('The number of updated documents was ', numberAffected); //Remove %d as numberAffected is not a number
});
res.redirect('/');
res.end();
};

.insertOne is not a function

I want to preface this by saying I have read several posts here regarding this issue.
I have a node/express/mongo app with the following:
app.js:
var express = require('express')
var bodyParser = require('body-parser')
var cors = require('cors')
var morgan = require('morgan')
var mongoose = require('mongoose')
var passport = require('passport')
var app = express()
// MongoDB Setup
var configDB = require('./config/database.js')
mongoose.connect(configDB.url)
app.use(morgan('combined'))
app.use(bodyParser.json())
// Check security with this
app.use(cors())
// load our routes and pass in our app and fully configured passport
require('./routes')(app)
app.listen(process.env.PORT || 8081)
console.log('We are up and running, captain.')
routes.js
const AuthenticationController = require('./controllers/AuthenticationController')
module.exports = (app) => {
app.post('/register', AuthenticationController.register)
}
My mongo schema file Account.js:
const mongoose = require('mongoose')
const bcrypt = require('bcrypt-nodejs')
const Schema = mongoose.Schema
var accountSchema = new Schema({
email: String,
password: String,
likesPerDay: { type: Number, min: 0, max: 250 },
followPerDay: { type: Number, min: 0, max: 250 },
unfollowPerDay: { type: Number, min: 0, max: 250 },
commentsPerDay: { type: Number, min: 0, max: 250 },
comment: String,
hashtags: [String]
})
// methods ======================
// generating a hash. We hash password within user model, before it saves to DB.
accountSchema.methods.generateHash = function (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null)
}
// checking if password is valid
accountSchema.methods.validPassword = function (password) {
return bcrypt.compareSync(password, this.local.password)
}
// create the model for users and expose it to our app
module.exports = mongoose.model('Account', accountSchema)
And finally my controller file AuthenticationController.js
const Account = require('../models/Account.js')
// var bodyParser = require('body-parser')
module.exports = {
register (req, res) {
Account.findOne({email: req.body.id}, function (err, account) {
if (err) {
console.log('Could not regster user')
throw err
}
if (account) {
console.log('account already exists')
} else {
Account.insertOne({email: req.body.email, password: req.body.password}, function (err, res) {
if (err) {
console.log('could not insert')
throw err
}
console.log('inserted account')
Account.close()
})
}
})
}
}
I am getting an error in my AuthenticationController file when I call Account.insertOne function.
I get the error that
TypeError: Account.insertOne is not a function
Now several of the posts here on stack have advised that I make sure that I am exporting the model from my model class, which I am doing, and that would fix this issue. Its weird because the findOne method seems to be fine, but when I call the insertOne i get an issue.
Am I missing something here?
A Mongoose model doesn't have an insertOne method. Use the create method instead:
Account.create({email: req.body.email, password: req.body.password}, function (err, doc) {
The Mongoose docs show how to create documents:
Either via Account.create():
Account.create({email: req.body.email, password: req.body.password}, function (err, res) {
// ...
})
Or by instantiating and save()ing the account:
new Account({email: req.body.email, password: req.body.password}).save(function (err, res) {
// ...
})
edit
as of mongoose documentation, try using
Account.create({ ...params ... }, function (err, small) {
if (err) return handleError(err);
// saved!
})
insertOne command is not available in mongoose directly as mentioned in Mongoose Documentation. If you want to use insertOne command then you need to use bulk command in order to send this command to MongoDB server. Something like below. I hope this works.
Account.bulkWrite([
{
insertOne: {
document: {email: req.body.email, password: req.body.password}
}
}
}]

CastError: Cast to ObjectId failed for value ...` at path "questions"

I'm currently building a Node backend with MongoDB / Mongoose and I seem to be having some problem with tying my data together. Specifically, I wish for all users to be able to submit a form (question form) which will then be added to the "questions" collection. In addition to being added to the questions collection, I also need to store a reference to all of the questions a user has answer directly inside of the user object.
Below you can check out my code. Whenever I make a POST requestion to /questions, it spits out this error. I should note that it successfully adds documents into the questions collection, and each question contains the ID of the user who created it, but the main problem is the user's questions array is not getting updated to include an ID value of submitted questions.
Models/User.js
const mongoose = require('mongoose'),
Schema = mongoose.Schema,
bcrypt = require('bcrypt-nodejs');
const UserSchema = new Schema({
email: {
type: String,
lowercase: true,
unique: true,
required: true
},
password: {
type: String,
required: true
},
profile: {
firstName: { type: String },
lastName: { type: String }
},
questions: [
{
type: Schema.Types.ObjectId,
ref: 'Question'
}
],
role: {
type: String,
enum: ['Member', 'Client', 'Owner', 'Admin'],
default: 'Member'
},
resetPasswordToken: { type: String },
resetPasswordExpires: { type: Date }
},
{
timestamps: true
});
/** Pre-save of user to database,
hash password if password is modified or new
*/
module.exports = mongoose.model('User', UserSchema);
Models/Question.js
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
// Schema defines how questions will be stored in MongoDB
const QuestionSchema = new Schema({
questionString: String,
answer: Boolean,
_createdBy : [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
],
},{
//user timestamps to save date created as .createdAt
timestamps: true
});
module.exports = mongoose.model('Question', QuestionSchema);
Controller/QuestionController.js
const jwt = require('jsonwebtoken'),
crypto = require('crypto'),
Question = require('../models/question'),
User = require('../models/user'),
config = require('../config/main');
function setQuestionInfo(request) {
return {
_id: request._id,
questionString: request.questionString,
answer: request.answer,
user: request.user
}
}
exports.addQuestion = function(req, res, next) {
User.findById(req.user.id, (err, user) => {
if (err) throw new Error(err);
// We create an object containing the data from our post request
const newQuestion = {
questionString: req.body.questionString,
answer: req.body.answer,
// in the author field we add our current user id as a reference
_createdBy: req.user._id
};
// we create our new post in our database
Question.create(newQuestion, (err, question) => {
if (err) {
res.redirect('/');
throw new Error(err);
}
// we insert our newQuestion in our posts field corresponding to the user we found in our database call
user.questions.push(newQuestion);
// we save our user with our new data (our new post).
user.save((err) => {
return res.send('sucess!');
});
})
});
}
Router.js
module.exports = function(app) {
// Initializing route groups
const apiRoutes = express.Router(),
userRoutes = express.Router(),
authRoutes = express.Router(),
questionRoutes = express.Router();
//=========================
// Auth Routes
//=========================
/** ROUTES BELOW WORK FINE -- ONLY DEALS WITH POST TO /questions
*
app.use middle ware sets /auth as auth route (everything goes through /api/auth)
apiRoutes.use('/auth', authRoutes);
apiRoutes.get('/dashboard', requireAuth, function(req, res) {
res.send('It worked! User id is: ' + req.user._id + '.');
});
// Set user routes as a subgroup/middleware to apiRoutes
apiRoutes.use('/user', userRoutes);
// View user profile route
userRoutes.get('/:userId', requireAuth, UserController.viewProfile);
// Test protected route
apiRoutes.get('/protected', requireAuth, (req, res) => {
res.send({ content: 'The protected test route is functional!' });
});
// Registration route
authRoutes.post('/register', AuthenticationController.register);
// Login route
authRoutes.post('/login', requireLogin, AuthenticationController.login);
*/
// Problem Area --> Making POST req to /questions
apiRoutes.post('/questions', requireAuth, QuestionController.addQuestion);
// Set url for API group routes
app.use('/api', apiRoutes);
};
You've your schema defined to accept question ids for a user.
questions: [
{
type: Schema.Types.ObjectId,
ref: 'Question'
}
After you save with Question.create(newQuestion, (err, question)... the callback attribute question has the updated data, one with the ObjectId.
Now you add this ObjectId value to your existing questions array that you got from findById on User model.
user.questions.push(question._id);
Mongoose will use the questionId to fill your question object when you use populate on questions array, but thats part for retrieving information.

mongoose schema with dynamic nested Object

I'm trying to create a Document Schema where I would have a dynamic Object. Example:
var ModuleSchema = new Schema({
name : String,
description : String,
type : String,
age : String,
options : {}
});
Is it possible to do the
options : {}
like that? with any arbitrary attributes inside. I'm getting TypeError: Cannot read property 'find' of undefined when I try to access a route /api/something to get all the documents in the collection. It might be because of the way I've defined the schema. any ideas?
EDIT:
var Module = require('../models/module');var auth =require('../config/auth');module.exports = function(router,Module){
router
.get('/api/modules' , auth.checkAuth, function(req,res){
Module.find(function(err,modules){
if(err){
res.send(err);
}else{
res.json(modules);
}
});
})
.post('/api/modules' , auth.checkAuth,function(req,res){
var module = new Module();
console.log(req.body);
module.name = req.body.name;
module.type = req.body.type;
module.description = req.body.description;
module.age = req.body.filename;
module.options = req.body.options;
module.save(function(err,module){
if(err){
res.send(err);
}else{
res.json({ id : module._id});
}
});
});
I use something like this.
// Importing the Users Mongoose Scheme
var User = require('../app/models/user');
var Feed = require('../app/models/ufeed');
module.exports = function(app) {
// A Route to get all users info
app.get('/user/all', function(req, res) {
// use mongoose to get all users in the database
User.find(function(err, user)
{
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err)
{
res.send(err);
}
// return all todos in JSON format
res.json(user);
});
});
Within my server.js file I am creating an app like so.
var app = express();
And then passing it to my routes file.
require('./app/routes.js')(app); // load our routes and pass in our app
I hope this helps.

not able to store the data to mongoDB

I am trying since 3 hours to store the data from html form to mongodb using noddejs.
while clicking on submit it shows another page which returns the data which has been submitted in json format but it is not being stored in database.
This is my app.js:
app.use(serveStatic(__dirname+"/index.html")).listen(8080);
var mongoUri = 'mongodb://localhost/test';
//Note that I am changing the dbname and trying to store data in different //db will also shows the same error
mongoose.connect(mongoUri);
var db = mongoose.connection;
db.on('error', function () {
throw new Error('unable to connect to database at ' + mongoUri);
});
console.log("connection successfull");
app.use(express.bodyParser());
app.use(express.static(__dirname + "/" ));
app.use(bodyParser.urlencoded({extended:true}));
app.post('/InquiryDetails', function(req,res){
res.json(req.body);
console.log(req.body);
});
require('./models/InquiryDetails');
app.listen(4000);
console.log('Listening on port 4000...');
this is my model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var myskyllSchema = new Schema({
name: String,
email: String,
state: String,
country: String,
school: String,
profession: String,
phone: Number
});
mongoose.model('InquiryDetails', myskyllSchema);
This is my controller:
var mongoose = require('mongoose'),
InquiryDetails = mongoose.model('InquiryDetails');
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
Any help will be appreciated.
Just replace the code in app.js :
app.post('/InquiryDetails', function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
res.send(req.body);
});
});
instead of :
exports.add = function(req, res) {
InquiryDetails.create(req.body, function (error, details) {
if (error) return console.log(error);
return res.send(details);
});
}
The reason is controller was unable to load and method add is not registered with post method. Now it is working.

Categories