How can I tell when findOneAndUpdate successfully updates a document? huh variable always returns the same thing (whether id is in the database or not) and doc is always null.
var query = {id : id };
var huh = schemaModel.findOneAndUpdate(query, obj, function(doc) {
console.log(doc);
if(doc) {
callback(doc);
} else {
errback('');
}
}
);
console.log(huh);
You are only passing one parameter to the callback in your findOneAndUpdate query.
I think that your query succeeds, but doc will always come null when you successfully update the object as it is the first parameter which is the err.
Also, I do not see the code for your callback function, so I am just presuming that it can be accessed in the scope of your function.
var query = {id : id };
var huh = schemaModel.findOneAndUpdate(query, obj, function(err, doc) {
if(err) {
return "Error spotted!";
} else {
return "Found & Updated";
}
}
);
console.log(huh);
By returning those values, you are basically assigning them to the huh variable and it should log accordingly. It serves as a logging mechanism.
Related
I'm working on MEAN stack to create some web services.
I thought of using ES6 for synchronizing mongodb find operations.
Here is the code(UserService):
var Todo = require('../models/user.js');
var db = mongoose.createConnection('mongodb://localhost:27017/abc');
var Users = db.model('User');
function *myGenerator() {
return yield Todo.find({});//Throwing Undefined function Todo.find
//return yield Users.find({}); //DOes not returns documents but returns a json object which has full mongodb database details
}
function getDocs(){
var iterator = myGenerator();
var firstYield = iterator.next();
}
return yield Todo.find({}) is throwing exception Undefined function Todo.find
return yield Users.find({}); does not return documents but returns a JSON object which has full mongodb database details
return yield Users.find({}).exec() returns following output
{ value:
Promise {
emitter:
EventEmitter {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined },
emitted: {},
ended: false },
done: false }
PS: I used --harmony node js option as well.
Could you please help me to get User rows/documents?
Todo.find({}); returns a Query object. You must call exec function on that object to execute the query. e.g.
Todo.find({}).exec(function (error, docs) {
if (error) {
// handle
}
if (docs) {
// yeah !!!
}
})
Also mongoose database connection is asynchronous. So any queries made before the connection is established obviously wont work. Here's a working example..
var mongoose = require('mongoose');
mongoose.Promise = Promise;
var db = mongoose.connect('mongodb://localhost:27017/test', (error) => {
if (error) {
throw error
}
console.log('DB Connected');
var Todo = require('./models/user.js');
var Users = db.model('User');
function *myGenerator() {
yield Todo.find({}); // Returns a Query object
//yield Users.find({}); // Returns a Query object
}
function getDocs(){
var iterator = myGenerator();
var firstYield = iterator.next();
// firstYield is a `Query` object
firstYield.value.exec((error, users) => {
if (error) {
throw error;
}
console.log(users);
})
}
getDocs();
});
var Todo = requires('models/user.js'); produces ReferenceError: requires is not defined
should be var Todo = require('models/user.js');
maybe even
var Todo = require('./models/user.js'); because 'models/user.js' is relative to the node_modules directory
return yield Todo.find({});
should be yield Todo.find({});
As far as I can see this code will throw an Exception.
Please provide the actual code and some more info like what version of node.js you are currently running ?
p.S I wrote this in the answers section because I have yet to earned the comment everywhere priveledge
This should be simple but it is surprisingly difficult and extremely frustrating. I am trying to overwrite an 'Object' field in mongodb with a new Object that the user creates in my client webpage. I have validated that all other fields I am passing to the update operation are in fact being updated, with the exception of the javascript object. Instead of it updating with the object I am passing (While I validated is being populated with the object I am passing through), it just updates it back to {} instead of whats being passed:
{ nodes:[ { w: 120, h: 80,type: 'InHive',left: 184,top: 90,text: 'item',query: 'hey',name: 'sample',id: '7686132d-6fcf-4a3b-baa2-b1c628e0b2d6' } ], edges: [], ports: [],groups: [] }
When I attempt to update the data field outside of the meteor method, directly from the mongo console interface, it overwrites that field successfully with the javascript object. What am I doing wrong here, because I cant for the life of me figure this one out?
Server Method
'updateOneWorkflow': function(id, field, object) {
this.unblock;
if (Meteor.userId()) {
var _username = Meteor.user().username;
MYCOLLECTION.update({
_id: id
}, {
$set: {
[field]: object, //this just gets reset back to {} whenever this update method is called
"metadata.last_modified_dt": new Date(), //this gets updated
"metadata.modified_by": Meteor.userId(), //this gets updated
'metadata.modified_by_username': _username //This gets updated
}
});
} else {
throw new Meteor.Error(403, "You are not authorized to perform this function");
}
}
Client Call:
var _jsonformat = toolkit.exportData();
var currentid = Session.get('rulesRowClicked')._id;
console.log(_jsonformat);
Meteor.call('updateOneWorkflow' , currentid, 'data', _jsonformat, function(err, res){
if(err){
toastr.error('Failed to save result ' + err);
}
else{
toastr.success('Saved workflow');
}
});
I believe your problem is stemming from this line: [field]: object. I don't believe that's a proper method of dynamically accessing an object's field. Instead, try to dynamically update the field as so:
'updateOneWorkflow': function(id, field, object) {
this.unblock;
if (Meteor.userId()) {
var _username = Meteor.user().username;
var newObj = {
"metadata": {
"last_modified_dt": new Date(),
"modified_by": Meteor.userId(),
"modified_by_username": _username
}
};
newObj[field] = object;
MYCOLLECTION.update({
_id: id
}, {
$set: newObj
});
} else {
throw new Meteor.Error(403, "You are not authorized to perform this function");
}
}
The issue was crazier than I expected. If you are using Meteorjs and you are using the Aldeed Schema 2 collection framework, it seems to completely ignore updates/inserts of json objects even if you set the field type to Object, unless you set up the exact same schema as the object (including nested array objects) and attach it to your collection. Dumbest thing Ive ever seen, no idea why nothing warns you of this. I removed the schema attachment and it worked.
Previously I had tried something like (with mongoose and promises):
var cursor = User.find({email: from.address, token: tokenMatches[1]});
and then
return cursor.update(
{'votes.title': b},
{'$set': { 'votes.$.category': a }}
).then(function (result) {
if(result.nModified == 0) {
return cursor.update({}, {'$push': { votes: { category: a, title: b }}}).then(function (res) {
ServerLog('updatePush', res);
return res;
});
}
});
But it always returned nModified = 0 for the first and second call. Until I found out that the cursor object actually has no update function. So why is it so? And why did it not throw an exception?
Model.find returns a Query object, not a cursor. Query does have an update method that lets you execute the query as an update operation.
router.get('/wiki/:topicname', function(req, res, next) {
var topicname = req.params.topicname;
console.log(topicname);
summary.wikitext(topicname, function(err, result) {
if (err) {
return res.send(err);
}
if (!result) {
return res.send('No article found');
}
$ = cheerio.load(result);
var db = req.db;
var collection = db.get('try1');
collection.insert({ "topicname" : topicname, "content": result }, function (err, doc){
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// And forward to success page
res.send("Added succesfully");
}
});
});
Using this code, I am trying to add the fetched content from Wikipedia in to the collection try1. The message "Added succesfully" is displayed. But the collection seems to be empty. The data is not inserted in the database
The data must be there, mongodb has { w: 1, j: true } write concern options by default so its only returns without an error if the document is truly inserted if there were any document to insert.
Things you should consider:
-Do NOT use insert function, its depricated use insertOne, insertMany or bulkWrite. ref.: http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#insert
-The insert methods callback has two parameters. Error if there was an error, and result. The result object has several properties with could be used for after insert result testing like: result.insertedCount will return the number of inserted documents.
So according to these in your code you only test for error but you can insert zero documents without an error.
Also its not clear to me where do you get your database name from. Is the following correct in your code? Are you sure you are connected to the database you want to use?
var db = req.db;
Also you don't have to enclose your property names with " in your insert method. The insert should look something like this:
col.insertOne({topicname : topicname, content: result}, function(err, r) {
if (err){
console.log(err);
} else {
console.log(r.insertedCount);
}
});
Start your mongod server in a correct path,i.e, same path as that of what you are using to check the contents of collection.
sudo mongod --dbpath <actual-path>
Basically, I'm trying to compare the user's answer for a question in a "null" or local MongoDB to a key in another MongoDB that was declared before.
I know that to get the _id of the declared MongoDB (the real databse) is to call this._id, which is evident when I run console log on the browser console.
But how can I retrieve the _id of the local MongoDB?
Thanks in advance for any help.
Here is the helper code:
Template.question.events({
"click .button": function(e){
e.preventDefault;
for (var i = 0; i < document.getElementsByName("choices").length; i++){
if (document.getElementsByName("choices")[i].checked){
var init = document.getElementsByName("choices")[i].value;
}
}
Answers.insert({answer: init});
if(Answers.find({answer: init}) === Quiz.find({_id: this._id}, {answer: init})){
console.log("The answers match.");
}
}
});
The last part of the code is me attempting to compare the answer field in the "Answers" DB, which is the local DB to the answers field in the Quiz DB, which is the declared, legitimate database.
Edit:
So I used user "gdataDan" suggestion and changed my code to include a function taking in the error and result parameters + I added an else statement to see if the event helper actually is functioning properly until the end:
Template.question.helpers({
title: function(){
return Quiz.find();
}
})
Template.question.events({
"click .button": function(e){
e.preventDefault;
for (var i = 0; i < document.getElementsByName("choices").length; i++){
if (document.getElementsByName("choices")[i].checked){
var init = document.getElementsByName("choices")[i].value;
}
}
var id = "";
Answers.insert({answer: init}, function(error, result){
if (error){
console.log("error: " + error);
} else if (result){
id = result;
}
})
if(Answers.find({_id: id}, {answer: init}) === Quiz.find({_id: this._id}, {answer: init})){
console.log("The answers match.");
} else {
console.log("Something went wrong.");
}
}
});
Turns out that console log prints "Something went wrong," even though the answers match between both databases. So I feel like the way I call the find function or the id's themselves don't match.
Edit#2:
I tried declaring the init variable outside the loop and tried using the $eq operator for MongoDB and still get the "Something went wrong" message in the console.
collection.insert will return the ID if there is no error.
var id = ''
Answers.insert({answer: init},function(error,result){
if(error) console.log('error: ' + error);
if(result) id = result;
});