Reputation: 3
I am implementing an approval system using Mongoose, Express and NodeJS.
Each post has 2 set of approvals.
I have implemented model as below:
Post Schema:
var PostSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
/..
.. Object related fields
../
Approval1: Object, //chidschema objects of approver
Approval2: Object
});
Approval Mapping Schema:
var ApprovalMapSchema = new Schema({
UserId: { type: ObjectId, unique: true, default: null },
Approver1Id: { type: ObjectId, default: null },
Approver2Id: { type: ObjectId, default: null }
});
I am trying to find the mapping first in my function and then update the main post object on save.
I need to retrieve both approver IDs before saving new Post.
Please suggest a good way to go about it. I am currently doing:
Update Post object with approver entries.
post.save(function(err, doc) { if (err) {} else { console.log({success: true, msg: 'Successful created new post', content: doc}); } });
/*var actId = activation._id, distributorId, ttlId;
var approvalMap = ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
else{
Approver1Id = appMap.Approver1Id;
Approver2Id = appMap.Approver2Id;
}
});
// Create child objects after this and update as subdocument
This is not working for me. Please Help!
Upvotes: 0
Views: 531
Reputation: 5606
I am having a difficult time understanding your question. But it sounds like you want to do something like this (you will need to modify this based on what you want to do, but hopefully it shows you one way of handling the async behavior):
//This will run a query that returns a document where userId == myUserId
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
//Once the query is complete function(err, appMap) will be called
//err will contain an error object if there was an error
//appMap will be the data returned by the query.
//within this block you can run another query
//for example
ApprovalMap.findOne({approved:'some variable'},function(err, secondQueryData){
if (err) throw err;
//after this query is complete function(err, secondQueryData) will be called
//once again the err argument will be an error, and the
//secondQueryData argument will contain your return data
//here you can do something with the data
//for example, log the results
console.log(secondQueryData)
})
});
As you can see, you can nest additional queries or steps within the callbacks of other queries. This will ensure things are run in the correct order. you may also want to checkout the npm async library, or a promise library like q or bluebird. They also have some great solutions for handling the async behavior in node.
Upvotes: 1
Reputation: 3
as per @user2263572 suggestion, went for async library.
this is how I implemented it now:
async.waterfall(
[
function(callback){
ApprovalMap.findOne({ userId: myUserId }, function(err, appMap) {
if (err) throw err;
else{
//..Create child approval elements and assign Ids from map
callback(err, Approver1Child, Approver2Child);
}
});
},
function(Approver1Child, Approver2Child, callback){
var post = new Post(req.body);
post.distApproval = Approver1Child;
post.ttlApproval = Approver2Child;
post.userId = myUserId;
callback(null, post);
}
],
function(err, post){
//creating new order
post.save(function(err, doc) {
if (err) {
}
else
{
console.log({success: true, msg: 'Successful created new post', content: doc});
}
});
}
);
Thanks a lot @user2263572!! Cheers!
Upvotes: 0