Gsuz
Gsuz

Reputation: 353

Meteor getting double insert on mongo database

The following code is an event to gathering information regarding expenses and done tasks into a bills database. Everytime I run this process I'm getting 2 entries into the bills database. The first entry is always empty and the second one has the entries I want.

'click .ConfirmCloseCase': function (event) {
  var caseID = Session.get('CurrentClosingCaseID');
  var TasksToChange = Tasks.find({caseID:caseID,done:true,billed:false});
  var ExpensesToChange = Expenses.find({caseID:caseID,billed:false});
  // Create new Entry into bills Database
  Bills.insert({"expensestotal":0,"taskstotaltime":0}, function(error, result) {

    // Set all Tasks to billed
    TasksToChange.forEach(function(task){
      Tasks.update(task._id, {$set: {"billed": true} })
      Meteor.call( 'BillsUpsert', result, {$push: {"tasks": task._id}} );
      Meteor.call( 'BillsUpsert', result, {$inc: {"taskstotaltime": task.hours}} );
    })

    // Set all Expenses to billed
    ExpensesToChange.forEach(function(expense){
      Expenses.update(expense._id, {$set: {"billed": true} })
      Meteor.call( 'BillsUpsert', result, {$push: {"expenses": expense._id}} );
      Meteor.call( 'BillsUpsert', result, {$inc: {"expensestotal": expense.amount}} );
    })

    Router.go('/Bills');
  })
},

The Meteor call is like so:

Meteor.methods({
  BillsUpsert: function( id, doc ){
    Bills.update( id, doc );
  }
});

My guess it that I'm getting 2 entries into the database is because the code is running asynchronously. Is this a correct assumption?... and as a followup is there an "easy" fix? :)

Upvotes: 2

Views: 132

Answers (2)

Gsuz
Gsuz

Reputation: 353

After much trial and error I found the problem. The double entry into my database was not related to the code I posted and was due to a stupid mistake of my part of calling the function twice from two different places in my code.

Sorry for wasting people's time with this post.

Upvotes: 1

Michel Floyd
Michel Floyd

Reputation: 20226

I don't think the asynchronous calls are the root cause of your problem but you can significantly simplify this code by moving all your inserts and updates to the server:

'click .ConfirmCloseCase': function (event) {
  Meteor.call('closeCase',Session.get('CurrentClosingCaseID'),function(err,result){
    if ( err ){
      // handle error
    } else {
      Router.go('/Bills');
    }
  });
}

Method:

Meteor.methods({
  closeCase: function(caseId){
    // you need to implement security checks on caseId here!

    // Synchronously create new document in Bills collection
    var billId = Bills.insert({ expensestotal: 0, taskstotaltime:0 });

    // Set all Tasks to billed
    var TasksToChange = Tasks.find({ caseID: caseID, done: true, billed: false });
    TasksToChange.forEach(function(task){
      Tasks.update(task._id, {$set: { billed: true} });
      Bills.update(billId,{ $push: { tasks: task._id }, $inc: { taskstotaltime: task.hours }} );
    )};

    // Set all Expenses to billed
    var ExpensesToChange = Expenses.find({ caseID: caseID, billed: false});
    ExpensesToChange.forEach(function(expense){
      Expenses.update(expense._id, {$set: { billed: true} });
      Bills.update(billId,{ $push: { expenses: expense._id }, $inc: { expensestotal: expense.amount }} );
    )};
  }

Upvotes: 1

Related Questions