lvarayut
lvarayut

Reputation: 15259

How to handle a call back hell in $http chaining?

I have many $http requests as following:

        Scholarship.loadMaxAcademicYear().success(function (AcademicYearId) {
            if (AcademicYearId) {
                Scholarship.deleteAllCurrentData(data).success(function () {
                    Scholarship.copyDataToCurrentYear().success(function(){
                        Scholarship.getPromises(null, AcademicYearId).then(function () {
                            $scope.isSuccess = true;
                            $timeout(function () {
                                $scope.isSuccess = false;
                                $scope.isSubmit = false;
                                $scope.confirmModal.close();
                            }, 5000);
                        }, function(err){
                            importError();
                        });
                    }).error(function(){
                        importError();
                    })
                }).error(function(){
                    importError();
                });
            }
        }).error(function (err) {
            importError();                
        });

I want to reduce the error callback to be only one at the end as following:

        Scholarship.loadMaxAcademicYear().success(function (AcademicYearId) {
            if (AcademicYearId) {
                Scholarship.deleteAllCurrentData(data).success(function () {
                    Scholarship.copyDataToCurrentYear().success(function(){
                        Scholarship.getPromises(null, AcademicYearId).then(function () {
                            $scope.isSuccess = true;
                            $timeout(function () {
                                $scope.isSuccess = false;
                                $scope.isSubmit = false;
                                $scope.confirmModal.close();
                            }, 5000);
                        }
                    })
                })
            }
        }).error(function (err) {
            importError();                
        });

I'm thinking of using the async but Angular might have some way to handle this kind of problem. Would it be possible to do so in AngularJs?

Upvotes: 0

Views: 91

Answers (1)

JLRishe
JLRishe

Reputation: 101690

You've still got a pyramid of doom even in your second example. The key here is to use the .then() method to allow promise chaining:

Scholarship.loadMaxAcademicYear().then(function(response) {
  var academicYearId = response.data;
  if (academicYearId) {
    return Scholarship.deleteAllCurrentData(academicYearId)
    .then(function() {
      return Scholarship.copyDataToCurrentYear();
    }).then(function() {
      return Scholarship.getPromises(null, academicYearId);
    }).then(function() {
      $scope.isSuccess = true;
      return $timeout(function() {
        $scope.isSuccess = false;
        $scope.isSubmit = false;
        $scope.confirmModal.close();
      }, 5000);
    });
  }
}).catch(function(err) {
  importError();
});

We can also shorten this a bit by using .bind():

Scholarship.loadMaxAcademicYear().then(function(response) {
  var academicYearId = response.data;
  if (academicYearId) {
    return Scholarship.deleteAllCurrentData(academicYearId)
    .then(Scholarship.copyDataToCurrentYear.bind(Scholarship))
    .then(Scholarship.getPromises.bind(Scholarship, null, academicYearId))
    .then(function() {
      $scope.isSuccess = true;
      return $timeout(function() {
        $scope.isSuccess = false;
        $scope.isSubmit = false;
        $scope.confirmModal.close();
      }, 5000);
    });
  }
}).catch(importError);

Upvotes: 1

Related Questions