function(dataValue, cb) {
req.app.db.models.User.find({
_id: { $ne: dataValue._id }
}, function(err, totalUser) {
if (!err) {
var len = totalUser.length;
if (len !== 0) {
req.app.utility.async.map(totalUser, function(each, callback) {
console.log(each);
req.app.utility.async.mapSeries(each.nonregisterContact, function(element, callback1) {
console.log('element', element.number);
console.log('dataValue', dataValue.mobileNumber);
console.log('kolka', Number(element.number) === Number(dataValue.mobileNumber));
if (Number(element.number) === Number(dataValue.mobileNumber)) {
each.registerContact.push(dataValue._id.toString());
each.nonregisterContact.splice(element, 1);
each.save(function(err, finalResult) {
if (!err) {
} else {
console.log(err);
}
})
callback1(null, null);
} else {
callback1(null, null);
}
}, function(err, final) {
if (!err) {
callback(null, null);
} else {
console.log(err);
}
});
}, function(err, result) {
if (!err) {
console.log('2');
return cb(null, dataValue);
} else {
console.log(err);
}
});
} else {
return cb(null, dataValue);
}
} else {
cb(err);
}
})
}
I don't get any response after each.save method call in the mapSeries method final callback.I am trying this solution.How i will do the same thing. How I resolve that and handle this kind of situation?
I tried to simplify code, but I'm not sure that my code realizes your needs. Also I cann't test it :D
dataValue, each, element, finalResult are very common names, so you should use them with caution to keep code is readable/supportable.
// very bad idea is include other libraries to app
var async = require('async');
var db = require('db'); // this module must export connection to db
...
function (dataValue, cb) {
// processUser use data from closure of current function => inside of current
function processUser (user, callback) {
async.mapSeries(user.nonregisterContact, function(contact, callback){
// Check and exit if condition is not satisfied. It's more readable.
if (Number(contact.number) !== Number(dataValue.mobileNumber))
return callback(null); // ignore user
user.registerContact.push(dataValue._id.toString());
user.nonregisterContact.splice(contact, 1);
user.save(function(err, finalResult) { // Is finalResult ignore?
if (err)
console.log(err);
callback(); // ingnore error
})
}, callback);
db.models.User.find({_id: { $ne: dataValue._id }}, function(err, userList) {
if (!err)
return cb(err);
if (userList.length == 0)
return cb(new Error('Users not found'));
// use named function to avoid stairs of {}
async.map(userList, processUser, cb);
})
};
Related
the below function is generating the "x" is not a function error, for the love of me I have no idea why this is happening? any help is much appreciated.
function updateShareholder() {
var date = moment().format('MM/DD/YYYY');
console.log('updateShareholder');
var data = {
companyID: agreement.applicant.applicantCompanyID,
userID: agreement.coSigner.coSignerID,
agreementID: agreement.agreement.agreementID,
stock: agreement.stock.stock
}
company_worker.updateShareholder(data, function(err, result) {
if (err) {
console.log(err);
res.send(err);
} else {
console.log('updateShareholder');
process.nextTick(function() {
emailNotification()
});
}
});
};
if it helps here is the company worker function that is called within.
module.exports.updateShareHolder = function(req, callback) {
console.log('updateShareHolder');
Company.update({
"_id": req.companyID,
"shareHolders.userId": req.userID
}, {
$push: {
"shareHolders.$.agreements": {
agreementID: req.agreementID
}
}
}, {
$set: {
"shareHolders.$.shares": ++req.shares
}
},
function(err) {
if (err) {
console.log(err);
callback(err, err);
} else {
console.log('updateShareHolder');
callback(null, 'success');
}
})
};
and this is the function that calls the so-called broken function
function moveOn() {
if (addShareHolder == 'true') {
process.nextTick(function() {
addShareholder()
});
} else if (updateShareholder == 'true') {
process.nextTick(function() {
updateTheShareholder()
});
}
};
There's a typo in the function name.
You are exporting module.exports.updateShareHolder and calling company_worker.updateShareholder. Notice the lowercase h,
Let's say i need to constantly collecting some data from a lot of clients and in parallel running some complex loop that solving some stuff with this data. How can i do it? Should i just write this in my piece of code:
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/views/index0.html');
});
io.sockets.on('connection', function(socket) {
// SOME STUFF WITH THE SOCKET
socket.on('disconnect', function(data) {
//SOME OTHER STUFF
});
});
while(...) {
//THE LOOP STUFF
}
Or i need to use the setTimeout() and setInterval() functions? How can i do the loop on the server that runs in parallel with the callbacks' stuff?
Don’t use while for make it, this block a thread. setTimeout() will run only once. You need to use setInterval() function.
You can use the async module to handle the async operation with the callback or use promise to avoid callback.
Here how I handle a complex async for each operation, that might helpfull to you get idea handeling ayncs forach
var cond = { _schedule: schedule_id }; // find curse by schedule id
Course.find(cond, function (err, courses) {
if (err) {
callback({ "success": false, "message": "Not able to update" });
} else {
async.forEachLimit(courses, 1, function (course, coursesCallback) {
async.waterfall([
function (callback) {
var schedule_date = moment(change_data.date).format('YYYY-MM-DD') + "T00:00:00.000Z"
var Assignmentcond = {
assignment_schedule_order: {
$gte: schedule_date
},
_course: course._id,
_schedule: schedule_id,
_user: userid
};
Assignment.find(Assignmentcond)
.populate({
path: '_course',
})
.lean()
.sort({ assignment_schedule_order: 1 })
.exec(function (err, AssignmentList) {
if (err) {
callback(null, '');
} else {
//console.log("------------------AssignmentList---------------------------");
//console.log(AssignmentList);
async.forEachLimit(AssignmentList, 1, function (ThisAssignmentCell, ThisAssignmentCellCallback) {
async.waterfall([
function (callback) {
var SearchObj = items;
var lebelObject = {};
for (var i = 0, flag = 0, insert = 0; i < SearchObj.length; i++) {
if (SearchObj[i].date == ThisAssignmentCell.assignment_schedule_date) {
flag = 1;
}
if (flag == 1 && SearchObj[i].label != "") {
if (ThisAssignmentCell.day == SearchObj[i].day_index) {
insert = 1;
var lebelObject = SearchObj[i];
break;
}
}
}
callback(null, ThisAssignmentCell, lebelObject, insert);
},
function (ThisAssignmentCell, SearchObj, insert, callback) {
console.log('----------------------');
console.log('ThisAssignmentCell', ThisAssignmentCell);
console.log('SearchObj', SearchObj);
console.log('----------------------');
if (insert > 0) {
var query = { _id: ThisAssignmentCell._id },
fields = {
assignment_date: moment(SearchObj.date).format('MM/DD/YYYY'),
assignment_schedule_date: moment(SearchObj.date).format('YYYY-MM-DD'),
assignment_schedule_order: new Date(SearchObj.date),
day: SearchObj.day_index,
dayNum: SearchObj.weekday_num
},
options = { upsert: false };
Assignment.update(query, fields, options, function (err, affected) {
callback(null, '');
});
} else {
// var cond = { _id: ThisAssignmentCell._id};
// Assignment.remove(cond)
// .exec(function (err, cnt) {
// callback(null, '');
// });
}
}
], function (err, result) {
// result now equals 'done'
console.log('done')
ThisAssignmentCellCallback();
});
}, function (err) {
console.log("Assignment For Loop Completed");
callback(null, AssignmentList);
});
}
});
}
], function (err, result) {
// result now equals 'done'
console.log('done')
coursesCallback();
});
}, function (err) {
console.log("courses For Loop Completed");
});
}
});
Currently I have the following callback system:
var saveTask = function(err, result) {
if (err) return callback(err, result);
var newid = mongoose.Types.ObjectId();
var task = new Task({
_id: newid,
taskname: req.body.name,
teamid: req.body.team,
content: req.body.content,
creator: req.user.userId
});
task.save(function (err) {
if (!err) {
log.info("New task created with id: %s", task._id);
return callback(null, task);
} else {
if(err.name === 'ValidationError') {
return callback('400', 'Validation error');
} else {
return callback('500', 'Server error');
}
log.error('Internal error(%d): %s', res.statusCode, err.message);
}
});
};
if (req.body.team) {
valTeam.isMember(req.body.team, req.user._id, function (err, done) {
if (err) {
saveTask('403', 'Not the owner or member of this team');
} else {
saveTask(null, true);
}
});
} else {
saveTask(null, true);
}
valTeam.isMember
exports.isMember = function(teamid, userid, callback) {
Team.find({'_id':teamid, $or:[{'creator': userid }, {'userlist': { $in : [userid]}}]}, function(err, result) {
if (err) return err;
console.log(result);
if (!result.length)
return callback('404', false);
else
return callback(null, true);
});
}
In short, if team is sent by POST, I'm checking if the user is member of that ID in valTeam.isMember. Am I using the correct syntax and best method to call back my saveTask function to save the task if the user is part of the team?
This code currently works, but I feel like there should be an easier way to do it? How could I use a promise to achieve the same thing?
Thanks in advance.
It's curious the fact that you create objects instead Schemas. However "every head is a different world", this is my way:
task.save(function(error, data){
if (error) {
trow error;
} else {
//Make whatever you want here with data
});
I am new to Node.js and mongoose, i am trying to query objects from a mongo collection using find({}) and the function is as follows :
schema.statics.listAllQuizes = function listAllQuizes(){
Model.find({},function(err,quizes,cb){
if(err){
return cb(err);
}else if(!quizes){
return cb();
}
else {
return cb(err,quizes);
}
});};
But when i call this function i get an error saying
return cb(err,quizes);
^
TypeError: cb is not a function
I am stuck at this point, can someone please help me with this, thanks in advance.
The callback should an argument to listAllQuizes, not an argument to the anonymous handler function.
In other words:
schema.statics.listAllQuizes = function listAllQuizes(cb) {
Model.find({}, function(err, quizes) {
if (err) {
return cb(err);
} else if (! quizes) {
return cb();
} else {
return cb(err, quizes);
}
});
};
Which, logically, is almost the same as this:
schema.statics.listAllQuizes = function listAllQuizes(cb) {
Model.find({}, cb);
};
Here's an example on how to use it:
var quiz = App.model('quiz');
function home(req, res) {
quiz.listAllQuizes(function(err, quizes) {
if (err) return res.sendStatus(500);
for (var i = 0; i < quizes.length; i++) {
console.log(quizes[i].quizName)
}
res.render('quiz', { quizList : quizes });
});
}
Assuming you have code somewhere that looks like this:
foo.listAllQuizzes(function (err, quizzes) {
...
});
Then your function listAllQuizzes is passed a callback:
schema.statics.listAllQuizzes = function (cb) {
Model.find({}, function(err, quizzes) {
if (err) return cb(err);
cb(null, quizzes);
});
};
(First: I'm sorry, I don't speak english very well!)
I wanna return the results of 3 finds in one array.
My code (next) is running well, but I'm in callback hell!
_Schema
.static('retrieveAll', function(cb) {
query = {};
this.find(query, function(err, data) {
if(err) {
cb(err, null);
return;
}
if(data)
all = data;
else
all = [];
_StoresModel.find(query).select('contact address').exec(function(err, data) {
if(err) {
cb(err, null);
return;
}
if(data) {
all = data.reduce(function(coll, item) {
coll.push(item);
return coll;
}, all);
}
_CustomersModel.find(query).select('contact address').exec(function(err, data) {
if(err) {
cb(err, null);
return;
}
if(data) {
all = data.reduce(function(coll, item) {
coll.push(item);
return coll;
}, all);
}
cb(null, all);
});
});
});
});
I've a FIND inside a FIND inside a FIND.
Is there anyway to improve this?
SOLUTION:
_Schema
.static('retrieveAll', function(cb) {
var model = this;
_async.parallel(
{ contacts: function(cb) {
model.find({}).exec(cb);
}
, stores: function(cb) {
_StoresModel.find({}).select('contact address').exec(cb);
}
, costumers: function(cb) {
_CostumersModel.find({}).select('contact address').exec(cb);
}
}
, function(err, data) {
if(err) {
cb(err, null);
return
}
var ret = [];
if(data.contacts.length > 0) {
ret = ret.concat(data.contacts);
}
if(data.stores.length > 0) {
ret = ret.concat(data.stores);
}
if(data.costumers.length > 0) {
ret = ret.concat(data.costumers);
}
cb(null, ret);
});
You can try using Promises.
(untested) example:
var RSVP = require('rsvp');
var all = [];
_Schema.static('retrieveAll', function(cb) {
query = {};
findPromise(this, query)
.then(function (data) {
all = data;
return findPromise(_StoresModel, query, 'contact address');
})
.then(function (stores) {
all = all.concat(stores);
return findPromise(_CustomersModel, query, 'contact address');
})
.then(function (customers) {
all = all.concat(customers);
cb(null, all);
})
.catch(function (err) {
cb(err, null);
});
});
function findPromise(Model, query, select) {
return new RSVP.Promise(function (resolve, reject) {
Model.find(query).select(select || '*').exec(function (err, data) {
return err ? reject(err) : resolve(data);
});
});
}
That example is using RSVP, but there are also other promise implementations such as Q and bluebird.
And a side note, you can use concat to concatenate arrays instead of using reduce.
take a look at npm Async. It a great library of different patterns that can be used on node.js.
You will probably want to use the waterfall if there is a Chronological priority or parallel pattern if they can all execute in parallel.
Some server-side promise libraries like q and bluebird would clean up your code substantially and eliminate the mess of callback hell.