0

My question is about promises. How can I use asn structure to do the following.

I try to delete a task. Tasks have documents.

For delete a task, first I get the task from from database, next get and delete task documents and finally delete the task.

All of this in a transaction of my database library. If something fails rollback transaction.

My initial idea is this code:

connection.beginTransaction(function (err) {

    getTaskById(1)    
    .then(getTaskDocuments)
    .then(deleteTaskDocuments)
    .then(deleteTask) 
    .then(function(){

       connection.commit(function (err) {
          if (err) {
             throw new Error()
          }    

           res.json();
       });

    }).catch(

       return connection.rollback(function() {
          res.status(500).json()
        })

    });

It will be never works, because deleteTask, need the result of getTaskById, how can I solve this?

I will can modify promises or create a new promises. The only 2 facts that I can't change is that I need the database transaction and the order of delete, first documents and last task

David
  • 1,116
  • 3
  • 18
  • 32

2 Answers2

0

I would suggest:

getTaskById(1).then(function (task) { 
   return getTaskDocuments(task)
          .then(deleteTaskDocuments)
          .then(function () { return task })
          .then(deleteTask) })
Dan D.
  • 73,243
  • 15
  • 104
  • 123
-1

The best way to do this is by using asnyc library in Node JS. To achieve the functionality you can use async.waterfall method to execute above transaction you can do something like this. I'm assuming that you have 2 different collection called task and taskdocuments from first you are getting task id and using that id you are checking taskdocuments collection, if document id is then you will delete it

var executeTransaction = function (req, res) {
    async.waterfall([
        getTaskId(req),
        getTaskDocuments,
        deleteTaskDocuments,
        deleteTask

    ], function done(error, success) {
        if (error) { alert('Something is wrong!'); }
        return alert('Done!');
    });
};

function getTaskId (req) {
    return function (callback) {
        var id = req.body;
        callback (null, id);
   }
}

function getTaskDocuments (id, callback) {
    return function (callback) {
       var document = function () { // do something here };
       callback (err, document);
    }
}

function deleteTaskDocuments (document, callback) {
    return function (callback) {
      var somethingmore = function () { // do something here };
      callback (err, task);
    }
}

function delete (document, callback) {
    return function (callback) {
      var somethingmore = function () { // do something here };
      callback (err, somethingmore);
    }
}

All task will execute in waterfall fashion, if any task fail you can exit from there it'll come to done block and you can send the appropriate response to the user.

Gaurav Sharma
  • 411
  • 7
  • 22
  • OP uses promises. `async.js` never is a good tool for them. – Bergi Apr 14 '18 at 13:09
  • @Bergi the question is about designing the problem and I've given my answer by having some assumption, can you please go through the question as well as my answer once again and retake your downvote – Gaurav Sharma Apr 14 '18 at 13:17
  • No, promises are by far superior to async.waterfall. I do not think that this is a good answer, I think that coding like this should be avoided. – Bergi Apr 14 '18 at 13:22
  • @Bergi I agree that promises are powerful in JavaScript but when we code in the Node JS or any JS our primary goal is to avoid callback chains which leads to callback hell which is a well known problem in JS, to avoid this problem we modularise the code and break it into chunks of functions, that exactly what I did in above answer using async library, I don't know why you are saying that it's not the right way – Gaurav Sharma Apr 14 '18 at 13:41
  • Promises are simpler, cleaner, faster, have better error handling and `async`/`await` syntax. They make even modularisation much easier as you can just return values, no need to mess around with passing callbacks. – Bergi Apr 14 '18 at 15:19