I am new to Mongodb and I am using findByIdAndUpdate which will update document but returning the old document ,
Here is my function ,
exports.createInner = function (req, res, next) {
console.log("req", req.body);
var innerFolderDetails = req.body.innerFolder;
Repository.findByIdAndUpdate(innerFolderDetails._id, {
$push: {
innerFolder: {
"foldername": innerFolderDetails.foldername,
"ismainFolder": innerFolderDetails.ismainFolder,
"parentfolderId": innerFolderDetails.parentfolderId,
}
}
}, function (err, response) {
if (err) return next(err);
console.log(response);
res.json(response);
});
};
findByIdAndUpdate can accept an options object as a third argument.
Model.findByIdAndUpdate(id, updateObject, {
new: true // get the modified document back
}, callback);
By default the value of new options is false
Related
I got an error like that: uncaughtException TypeError: cb is not a function
I think this error is caused by callback error but I don't know why I have this error.
app.put('/badge/student_badge/:id', upload, (req, res, next) => {
const name = req.body.name;
let data = {
name: name
}
badger.updatePersonBadge({
id: req.params.id
}, data, (err) => {
if (err) return next(err);
res.status(201).json({
message: 'Post updated successfully!'
});
});
});
function updatePersonBadge(options, cb) {
schemas.badger.then(b => {
b.findById({
_id: options.id
}, (err, resp) => {
if (err) return cb(err);
if (!resp) return cb("no badge found");
name = options.name;
title = resp.title;
points = resp.points;
updateBadge(name, title, points, cb);
cb(null, resp);
})
})
}
function updateBadge(name, title, points, cb) {
const dateCreated = new Date(),
dateUpdated = dateCreated;
registerSchemas.personModel.then(p => {
p.findOneAndUpdate({
name: name
}, {
$push: {
badges: [{
title: title,
points: points,
dateCreated: dateCreated,
dateUpdated: dateUpdated
}]
}
}, (err, resp) => {
if (err) return cb(err);
if (!resp) return cb("no person found");
})
})
}
You are not passing the cb argument and if it's optional (at least seems it should be) the function misses an if statement:
updatePersonBadge(options, cb) { // << cb (callback) argument expected
// ...
cb(null, resp); // cb called therefore not optional (Its needed)
If you use it like updatePersonBadge(aaa) instead of updatePersonBadge(aaa, myCallbackFn) the cb() is undefined but expressed as a function call - that does not exist.
You could instead make it optional (if that's the case):
//...
if(cb) cb(null, resp); // call the cb function if cb argument exists
or if you want to be more specific:
//...
if(cb && typeof cb === 'function') cb(null, resp);
instead of passing a function you're passing data:
badger.updatePersonBadge({}, data, errFn);
I assume this is the place from where you are calling updatePersonBadge. IF yes, then you are passing callback as a third argument, You have to use them correctly.
badger.updatePersonBadge(
{
id: req.params.id
},
data,
(err) => {
if (err) return next(err);
res.status(201).json({
message: 'Post updated successfully!'
});
});
In the example the problem is parameter mismatch, In place of callback you send data
app.put('/badge/student_badge/:id', upload, (req, res, next) => {
const name = req.body.name;
let data = {
name: name
}
badger.updatePersonBadge({id:req.params.id}, data, (err)=>{. -- three arguments passed
if (err) return next(err);
res.status(201).json({
message: 'Post updated successfully!'
});
});
});
Where in function definition you have only 2 parameters defined.
where it should be 3 parameters / that particular scenario should be validated.
I'm getting user.update is not a function when running this code. I have been unable to find good mongo/mongoose documentations online.
//Add Event
app.post("/addEvent", (req, res, next) => {
const event = req.body.event;
console.log(req.user.id);
console.log(event);
User.find({ _id: req.user.id }, function(err, user) {
if (err) {
console.log(err);
return next(err);
}
if (user) {
user.update(
{
_id: req.user.id
},
{
$push: { events: event }
}
);
}
res.end();
});
});
};```
Try this, I guess it might help you.
app.post("/addEvent", (req, res, next) => {
const event = req.body.event;
console.log(req.user.id);
console.log(event);
User.findById({ req.user.id }, async function(err, user) {
if (err) {
console.log(err);
return next(err);
}
if (user) {
User.updateOne(
{
_id: req.user.id
},
{
$push: { events: event }
}
);
}
res.end();
});
});
};
I also recommended you using findByIdAndUpdate or findOneAndUpdate with necessary options in your case. Or findOne instead of find because find returns you [array] of documents, instead of one document, so if you'll be using async/await like that:
const docs = Users.find(query,callback)
They only way to access necessary document will be docs[n] where n is number of doc in resulting array.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I'm trying to create a function that will query a mongo db and then return the result, then render it on a page.
I'm just currently trying to console.log the objects to find out why this isn't working:
var getMarkets = function (marketID) {
MongoClient.connect('mongodb://localhost:27017/test', function(err, db){
db.collection("new-test-2", function (err, collection) {
collection.find({"ID": parseInt(marketID, 10)}).toArray(function(err, items) {
console.log(items);
return items;
});
});
});
};
router.get('/markets/:marketid', function(req, res, next) {
var marketobj = getMarkets(req.params.marketid);
console.log(marketobj);
res.render('api', { title: 'API', marketid: marketobj });
});
The log nested inside the function works fine, but then the log inside the routing object returns undefined. What's going on here? I have a feeling it has to do with asynchronous callbacks but I'm not able to reason about it.
Thanks a ton.
Use callback function to access data
var getMarkets = function (marketID , callback) {
MongoClient.connect('mongodb://localhost:27017/test', function(err, db){
db.collection("new-test-2", function (err, collection) {
collection.find({"ID": parseInt(marketID, 10)}).toArray(function(err, items) {
console.log(items);
//return callback
return callback(items);
});
});
});
};
router.get('/markets/:marketid', function(req, res, next) {
getMarkets(req.params.marketid , function(marketobj){
if(marketobj){
console.log(marketobj);
res.render('api', { title: 'API', marketid: marketobj });
}else{
// do whatever you want
res.render('api', { title: 'API', marketid: {} });
}
});
});
Mongodb connection and find operations are asynchronous functions. So you need to use callback to return result. Just return inside function doesn't work.
var getMarkets = function (marketID, callback) {
MongoClient.connect('mongodb://localhost:27017/test', function(err, db){
db.collection("new-test-2", function (err, collection) {
collection.find({"ID": parseInt(marketID, 10)}).toArray(function(err, items) {
if(err)
callback(err)
else {
console.log(items);
callback(null,items);
}
});
});
});
};
router.get('/markets/:marketid', function(req, res, next) {
getMarkets(req.params.marketid, function (err, marketobj) {
console.log(marketobj);
res.render('api', { title: 'API', marketid: marketobj });
});
});
You can use promises also.
I'm using mongodb for pretty much everything in my node.js application, and now i want create a restful application, so, i did that:
I'm trying to do just the get method, for now:
restApi.js:
var restAPI = {
get: function(method, model, sort, limit, options) {
if (method !== 'get') {
return;
}
model.find(options).sort(sort).limit(3).exec(function (error, result) {
if (error) {
return error;
} else {
return result;
}
});
},
};
And now i can require this in my route:
var restApi = require('restApi');
and use like this:
app.get('/', function(req, res, next) {
var result = restAPI.get('get', Event, 'date', 3, {'isActive': true});
res.render('/', {
result: result
});
});
Is not working, the result is undefined. Why??
How can i transform this in a async function with callback? This is possible?
Thanks! :)
You're not returning anything from restApi.get. If you're using mongoose, you could return a Promise easily enough:
var restAPI = {
get: function(method, model, sort, limit, options) {
if (method !== 'get') {
return;
}
return model.find(options).sort(sort).limit(3).exec();
},
};
Then you can use it like this:
app.get('/', function(req, res, next) {
restAPI.get('get', Event, 'date', 3, {'isActive': true}).then( function ( result ) {
res.render('/', {
result: result
});
}).catch( error ) {
// Render error page and log error
});
});
It is because your model is async. You have to pass callbacks.
Using async way is better because it is not blocking your application while waiting for response.
Example on your case:
restApi.js:
var restAPI = {
get: function(method, model, sort, limit, options, cb) {
if (method !== 'get') {
return cb("Method must be GET");
}
model.find(options).sort(sort).limit(3).exec(function (error, result) {
if (error) {
return cb(error);
} else {
return cb(null, result);
}
});
},
};
And now i can require this in my route:
var restApi = require('restApi');
and use like this:
app.get('/', function(req, res, next) {
restAPI.get('get', Event, 'date', 3, {'isActive': true}, function(err, result){
if(err)
return res.render("Error:" + err)
res.render('/', {
result: result
});
});
});
I've added cb argument to your REST API function so it is called when model async operation is done.
Router handler passes it's callback and prints output when operation is finished.
I'm new to expressJS and i'm wondering what is the best way to requery the database (mongo in my case) to get all the records after one is added.
exports.get = function (db) {
return function (req, res) {
var collection = db.get('notes');
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
};
};
exports.create = function (db) {
return function (req, res) {
var title = req.body.title;
var note = req.body.note;
var collection = db.get('notes');
// Insert/update the note
collection.insert(
{
"title": title,
"note": note
},
function (err, doc) {
// If it failed, return error
if (err) {
res.send("There was a problem adding the information to the database. Error: "+err);
} else {
//res.redirect('/');
//res.json(db.get('notes'));
// WHAT IS THE BEST THING TO DO HERE TO GET ALL THE RECORDS INCLUDING THE ONE I'VE JUST ADDED?
exports.get(db);
}
}
);
}
};
I would replace
exports.get(db);
for
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
The reason is that you are invoking this in the callback, AFTER the record has been inserted
Your exports.get function return a function, a kind of middleware I see.
Repplace
exports.get(db);
by
exports.get(db)();