vinoli vinoli - 2 months ago 16
AngularJS Question

Sequential promisses

I've to get four response's promises, but to do it firstly I've to call every function in sequence. From the first to the last. You can see into my code that I called the next function in the promise callback from last called function.

But the code doesn't look appropriate, so I need to know if is there someway to do it better.

Any suggestion?

My best regards,

Vinoli

$scope.createPayment = function() {
var dados = $scope.card;
// get first promise
PagamentoMP.createToken(dados)
.then(
function(result) {
dados.token = result;
// get second promise
PagamentoMP.guessPaymentMethod(dados)
.then(
function(result) {
dados.paymentMethod = result;
// get third promise
PagamentoMP.getIssuers(dados)
.then(
function(result) {
dados.issuer = result;
// get fourth promise
PagamentoMP.getInstallments(dados)
.then(
function(result) {
dados.installments = result;
},
// error for fourth promise
function(result) {
console.log("getInstallments PAGAMENTOMP -> Failed to get the name, result is " + result);
}
);
},
// error for third promise
function(result) {
console.log("getIssuers PAGAMENTOMP -> Failed to get the name, result is " + result);
});
},
// error for second promise
function(result) {
console.log("guessPaymentMethod PAGAMENTOMP -> Failed to get the name, result is " + result);
});
},
// error for first promise
function(result) {
console.log("createToken PAGAMENTOMP -> Failed to get the name, result is " + result);
});
};

Answer

Instead of doing this,

a().then(function(result) {
    b(result).then(function(result) {
        c(result).then(function(result) {
            console.log("done");
        });
    });
});

you can chain all the promises at the top level.

a()
    .then(function(result) {
        return b(result);
    })
    .then(function(result) {
        return c(result);
    })
    .then(function(result) {
        console.log("done");
    });

This same pattern can be used in your code.

To catch errors, add a .catch at the end of the chain if you want one error handler for all errors in the chain.

a()
    .then(function(result) {
        console.log("done");
    })
    .catch(function(err) {
        console.error(err);
    });

For separate error handlers at each step, you can do something like this:

a()
    .catch(function(err) {
        console.log("error in a");
        throw err;
    })
    .then(function(result) {
        return b()
            .catch(function(err) {
                console.log("error at b");
                throw err;
            });
    })
    .then(function(result) {
        return c()
            .catch(function(err) {
                console.log("error at c");
                throw;
            });
    });

Each error handler needs to call throw so that it does not continue down the chain when an error happens.