Node.js MongoDB collection.update() callback never called - node.js

Can anyone explain why the callback below is never getting called ?
The update works by the callback is never called. Did I miss something ?
collection.update({_id:partner._id},
{$set: {
groups: newGroups
}
},
{ upsert: false, w: 1 },
function(err, status){
console.log("update callback ");
if (err){
console.log("Error updating "+err.message);
callback(false);
} else {
console.log("Record updated as "+JSON.stringify(status));
callback(true);
}
}
);

You can wrap this in a function with a callback as a param:
//Except for callback as a parameter, every parameter is not compulsory
function yourFunctionName(id, newGroups, callback) {
collection.update({
_id: partner._id
}, {
$set: {
groups: newGroups
}
}, {
upsert: false,
w: 1
},
function(err, status) {
console.log("update callback ");
if (err) {
console.log("Error updating " + err.message);
callback(false);
} else {
console.log("Record updated as " + JSON.stringify(status));
callback(true);
}
}
)
}
Then call the function like this:
yourFunctionName(params, function(result) {
//Do anything with the result
});
If you want to understand how callback functions work, this might help you.

For example in node(sailsJs)
Model.update({id:'xxxxxxxxxxxxxxxx'},{name:'Flynn'}).exec(function afterwards(err, updated){
if (err) {
//handle error here!
return;
}
console.log('Updated user to have name ' + updated[0].name);
});

Related

How to avoid duplicate records when inserting data to db using "async" library

const obj =[
{userName:'a',firstName:'kote',lastName:'perumalla '},
{userName:'a',firstName:'kote',lastName:'perumalla '},
{userName:'as',firstName:'koteswararaO',lastName:'perumalla'},
{userName:'as',firstName:'koteswararaoH',lastName:'perumalla'},
];
async.each(obj,function(item,callback){
MongoClient.connect(url,{ useNewUrlParser: true }, function(err, db) {
const DaTa = db.db("mydb");
const asa =item.userName; DaTa.collection("Campus").find({userName:item.userName}).toArray(function(err, result) {
if(result.length <=0){
DaTa.collection("Campus").insertMany(obj,function(err,result){
if(result){
return callback();
}
})
}
else{
DaTa.collection("Campus").updateOne({userName:item.userName},{$set:{"firstName":item.firstName}},function(er,result){
console.log(result +'1 record is updated')
if(result){
return callback();
}
})
}
db.close();
callback('Done');
})
});
},function(err,result){
console.log('completed')
})
I am using .each method of async package in Nodejs. I want to avoid insertion of the duplicate records to the MongoDB database.
Please tell me what part of my code should be changed for achieving async insertion of unique records.
You can define a unique index in MongoDB.
db.collectionName.createIndex( { "userName": 1 }, { unique: true } );
var DaTa;
MongoClient.connect(url,{ useNewUrlParser: true }, function(err, db) {
DaTa = db.db("mydb");
async.eachSeries(obj,function(item,callback){
console.log("*****************************")
const asa =item.userName;
// DaTa.createIndex( { "_id": 1 }, { unique: true } );
console.log("item: ",item)
DaTa.collection("Campus").find({userName:item.userName}).toArray(function(err, result) {
console.log(result.length)
console.log("result: ", result)
if(result.length <=0){
console.log("doc not found")
DaTa.collection("Campus").insert(item,function(err,result){
if(result){
callback();
}
})
}else{
console.log("doc found")
DaTa.collection("Campus").update({userName:item.userName},{$set:{"firstName":item.firstName}},function(er,result){
// console.log(result +'1 record is updated')
console.log("doc update result: ",result.result)
if(result) {
callback();
}
})
}
})
}, function(err,result){
console.log('############ completed ##################')
})
// db.close()
});

Finish execution if first query returns a value Node.js Express.js mongoDB

Before starting, please mind that i have been searching this over 2+ hours, the answer will be simple i know but i couldnt get it to work . i am new to express node mongodb,
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("EXISTS");
//I WOULD LIKE TO EXIT IF THIS LINE EXECUTES
}
}
});
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("CREATED 201");
} else {
res.send("Failed to insert");
}
}
});
db.close();
});
my goal is to check if an user doesnt exists with given username, i would like to insert that to the DB.
i would like to exit if my query finds an match and arrange such that insertOne wont execute. please enlighten me!!
Once you are not using the async/await syntax you will have to nest the calls to MongoDB, so they execute in series. You can also use a module like async to achieve this.
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
if (result) {
db.close();
return res.send("EXISTS");
}
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
db.close();
if (result) {
return res.send("CREATED 201");
}
res.send("Failed to insert");
});
});
});
Try this
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
//put the error logic
}
else {
if (result) {
//Send the response
return result;
}
else{
// if above if block fails it means that user does not exist
//put the insert logic
}
});

How to find a record and insert the same record in Mongoose?

Here I want to get a record and I need to insert the same record with slight modification. But I can't see the data in my new record which I found in my get record. Here is what I tried, can anyone help me? I think the problem is with this line var institution = new Institution(data);:
Institution.find({_id:i._id}).exec(function (err, result) {
if(result)
transferData(result);
}
});
});
}
function transferData(data){
var institution = new Institution(data);
institution.name = 'xxxx';
institution.save(function (err, data) {
if (err) {
return res.status(400).send({ message: errorHandler.getErrorMessage(err) });
} else {
console.log('Data Inserted Successfully');
}
});
}
find() returns an array of docs that match the criteria in the callback hence the line
var institution = new Institution(data);
will not work as it's expecting a Document not an array.
You could use findById() method as:
Institution.findById(i._id).exec(function (err, result) {
if (result) transferData(result);
});
function transferData(data) {
var institution = new Institution(data);
institution.name = 'xxxx';
institution.save(function (err, data) {
if (err) {
return res.status(400).send({ message: errorHandler.getErrorMessage(err) });
} else {
console.log('Data Inserted Successfully');
}
});
}
A much better approach would involve the findByIdAndUpdate() method:
Institution.findByIdAndUpdate(i._id, {name: 'xxxx'}, {upsert: true}, function (err, data) {
if (err) {
return res.status(400).send({ message: errorHandler.getErrorMessage(err) });
} else {
console.log('Data Inserted Successfully');
}
);

Node JS: Data is not reaching next .then()

I am not able to change the status from o to 1. The server is returning 500 . I don't know what is wrong I have done everything fine why its not pushing.
function changeAdminStatus(req, res, next){
getSuperAminById(req.params.id)
.then(function(data){
if(data.account.status == 1)
{
console.log(data);
Admin.findByIdAndUpdate(data._id, {
$push: {
'account.status' : 0
}
}, function(err, doc) {
if (err) {
res.sendStatus(500);
}
else if(doc) res.sendStatus(200);
else res.sendStatus(200);
}
);
}
in second line use return will take the result to the next .then
function changeAdminStatus(req, res, next){
return getSuperAminById(req.params.id)
.then(function(data){
if(data.account.status == 1)
{
console.log(data);
Admin.findByIdAndUpdate(data._id, {
$push: {
'account.status' : 0
}
}, function(err, doc) {
if (err) {
res.sendStatus(500);
}
else if(doc) res.sendStatus(200);
else res.sendStatus(200);
}
);
}
Are you setting MongoDB like that
$push: {
'account.status' : 0
}
instead
$push: {
'account' :{ 'status' : 0 }
}

Node.js : res.redirect("back") got Error('Can\'t set headers after they are sent.');

I have a little problem on an express.js app.
Can't redirect back after several actions with callbacks.
My applications works with objects called "markers" and they are rated by "sub categories"
The goal of these actions is to merge 2 or more subcategories, move all markers from old to the new subcategoy, and finally, delete the old sub category.
Here is the code :
The action called after checked 2 or more subcategories :
exports.postMergeSubCategories = function(req, res) {
"use strict";
var data = {};
data.subCategories = req.body.subCategoriesChecked;
data.enName = req.body.subCategory.enName;
data.frName = req.body.subCategory.frName;
data.deName = req.body.subCategory.deName;
if (data.subCategories.length > 1) {
sscategoryMapper.merge(data, function(err, sscategory) {
if (err) return console.log(err);
console.log ('Sub categories merged !');
req.flash('mergeMessage', 'Merge completed!');
res.redirect("back");
});
} else { // error
console.log('Error while merge sub categories. It seems the number of sub categories checked less 2');
req.flash('mergeMessage', 'An error occured whil merge');
res.redirect("back");
}
};
The function sscategoryMapper.merge :
module.exports.merge = function(data, callback) {
async.waterfall([
function(callback){ // create new sub category
save(data, function(err, sscategory) {
if (err) return callback(err);
callback(null, sscategory._id);
});
},
function(sscategoryId, callback){ // update marker2sscategory
async.each(data.subCategories.split('|'), function(oldSscategoryId, err) { // for each subcategories, update markers2sscategory and remove the old subcategory
async.waterfall([
function(callback) { // update maker2sscategory to set the new sscategoryId to all target markers
marker2sscategoryMapper.update(sscategoryId, oldSscategoryId, function(err) {
if (err) return callback(err);
callback(null, oldSscategoryId);
});
},
function(oldSscategoryId, callback) { // delete the old sscategory
remove(oldSscategoryId, function(err) {
if (err) return callback(err);
callback();
});
}
], function(err) {
if (err) return callback(err);
callback();
});
}, function(err) {
callback();
});
callback(null, sscategoryId);
}
], function (err, result) {
if (err) return callback(err);
callback(null, result);
});
};
UPDATE
First problem here : I called 2 times the callback ... This piece of code moved to that :
}, function(err) {
callback(null, sscategoryId);
});
}
], function (err, result) {
if (err) return callback(err);
callback(null, result);
});
};
UPDATE END
The function marker2sscategoryMapper.update :
module.exports.update = function(to, from, callback) {
// update marker2sscategory with the new subcategory
dbMarker2sscategory.update({'_sscategory' : from}, {
'_sscategory' : to
}, {multi: true}, function(err) {
if (err) return callback(new Error(err));
callback(null, to);
});
}
And the function remove :
var remove = module.exports.remove = function(id, callback) {
dbSscategory.remove({'_id' : id}, function(err) {
if (err) return callback(new Error(err));
callback(null, id);
});
};
If I comment "res.redirect("back")", it will works.
Else, the error is : "Error('Can\'t set headers after they are sent.');" 2 times.
I read that one of the causes can be duplicate callbacks ... But I don't see that in my code.
Appreciate your help.

Resources