Node.js and mongoose update parameters - javascript

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();
};

Related

Why the data is being stored twice using mongoose?

I want to save a number of data in a property call cases. What I did was to iterate a list of data that I want to store, and then adding each data to the document's property. But the problem is that each data is being stored twice. I found a person in github who had the same issue, he said the problem was with nodemon, but I ran the sever again without nodemon and is the same problem.
Also found a question in stack saying that when a callback is applied it results in saving it twice, also the case is diferent from mine:
Why does using mongoose callback result in saving data twice?
I tried removing the callback, but I still have the same problem. (I dont think that a callback might do that)
This is the code:
var UserSchema = Schema({
user: {type: String},
password: {type: String},
name: {type: String},
privilege: {type: String},
cases: {type: Array}
})
var user = db.model('User', UserSchema , "users");
app.post("/addCases", function(req, res){
user.find({user: req.body.user}, async function(err, doc) {
if(err) {
console.log(err);
} else {
for (const iterator of req.body.list) {
await user.updateOne({user: req.body.user},
{ $push: {cases: iterator}}, {useFindAndModify: false}, function(err, raw) {
if(err) {
console.log(err);
} else {
console.log(value + ' <----- Value');
}
});
}
}
});
});
I think your problem might be related to you not ending the request in your server's code. After doing the modifications in your db, you should send a response to your front-end, if not it might try to repeat the request and you would end up with your endpoint being called two times.
Try something like:
app.post("/addCases", function(req, res){
user.find({user: req.body.user}, async function(err, doc) {
if(err) {
console.log(err);
} else {
for (const iterator of req.body.list) {
await user.updateOne({user: req.body.user},
{ $push: {cases: iterator}}, {useFindAndModify: false}, function(err, raw) {
if(err) {
console.log(err);
} else {
console.log(value + ' <----- Value');
}
});
}
}
// New code
res.json({ ok: true });
});
});

getting error "user.save is not a function" while trying to update a doc

I am updating a document according to the code
var express = require('express');
var router = express.Router();
var user = require('./user');
router.put('/:username/email',
function(req, res, next) {
console.log("control check");
next();
},
email.acquire,
function(req, res) {
console.log("control check");
var username = req.params.username;
var address = req.body.email;
console.log(address);
user.find({
'username': username
}, function(err, user) {
if (err) {
throw (err);
console.log('ERROR WHILE PUT EMAIL');
} else {
console.log('success while PUT email');
user.email = address;
user.save(function(err, updatedUser) {
if (err) throw (err);
res.status(200).send(updatedUser)
});
}
});
});
module.exports = router;
but am getting the error:
events.js:183
throw er; // Unhandled 'error' event
^
TypeError: user.save is not a function
the code for user.js is
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
username: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
var user = mongoose.model('user', userSchema);
module.exports = user;
I already tried to create an object out of the model but to no avail.
and yes there exist a collection called "user".
The user returned from the find() callback will be an array of mongoose documents, hence why it is complaining. Either use the findOne() method which returns a single Mongoose document that has the save method or use findOneAndUpdate() for an atomic update.
You also need to be unambigious with variable naming since you have duplicate user variables, one for the mongoose model and another for the callback parameter.
Using findOneAndUpdate() follows:
user.findOneAndUpdate(
{ 'username': username },
{ '$set': { 'email', address } },
{ 'new': true /*, 'upsert': true */ }
function(err, updatedUser) {
if (err) {
throw (err);
console.log('ERROR WHILE PUT EMAIL');
} else {
console.log('success while PUT email');
res.status(200).send(updatedUser)
}
}
);
User.find returns array of the result, Use findOne. Don't use the same variable name it creates confusion.
user.findOne({
'username': username
}, function (err, userData) {
if (err) {
throw (err);
console.log('ERROR WHILE PUT EMAIL');
} else {
if (userData) {
console.log('success while PUT email');
userData.email = address;
userData.save(function (err, updatedUser) {
if (err) throw (err);
res.status(200).send(updatedUser)
});
}else{
res.status(200).send('Some response')
}
}
});

Module.exports returns undefined with Mongoose call

I keep getting an undefined return on my find call with Mongoose. My result
in my exports file doesn't get logged, but it will work if I return a simple string outside my Projects.find call.
I'm passing req & res and they are logged correctly in my exports file, so don't think they have anything to do with the problem. Any ideas what's going wrong?
routes.js
var proj = require('./exports/projects');
app.use(function(req, res, next){
//repsonse: undefined
console.log('response: ' + proj.test(req, res));
next();
});
exports/projects.js
var Projects = require('../models/projects');
module.exports = {
test: function(req, res) {
Projects.find({'owner':req.user.id}, function(err, result) {
if (err) return '1';
if (!result)
return null;
else
return result;
});
}
};
models/projects.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var shortid = require('shortid');
var Projects = new Schema({
projectid: String,
pname: { type: String, required: true, trim: true },
owner: { type: String, required: true, trim: true },
status: { type: String, default: '0' },
team: String,
archived: { type: Boolean, default: '0' },
created_at: Date
});
Projects.pre('save', function(next) {
var currentDate = new Date();
this.created_at = currentDate;
this.projectid = shortid.generate();
next();
});
module.exports = mongoose.model('Projects', Projects);
It is due to asynchronous nature of the Project.find() method. You are trying to return a value in asynchronous function, which gets completed after some time. Thus is gets undefined value in return while executing proj.test(req, res) in console.log('response: ' + proj.test(req, res));.
Solution
Need to pass a callback function, which gets executed once the find operation is done.
routes.js
app.use(function(req, res, next){
proj.test(req,res,function(result){
console.log('response',result);
});
next();
});
exports/projects.js
module.exports = {
test: function(req, res, cb) {
Projects.find({'owner':req.user.id}, function(err, result) {
if (err) return cb(1);
if (!result)
return cb(null);
else
return cb(result);
});
}
};

Can't delete a document from Mongodb via Express route

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.

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