Search code examples
angularjsajaxpromisedeferred

AngularJS Reusability with deferred and promise


I am beginner using the deferred promise and could not find exact answers for the questions I have.

  • Deferred promise is really recommended even for single simple ajax($http angularjs) call? I know it is good if we have many ajax calls in sequence or same time.

  • Second question is about reusability. I have an ajax call to rest service in default page loading to show a list of items. When the filter drop down gets changed, then want to call same method in service for reusing it. But it brings same result as earlier, so I had to use completely different one. Code is given below. Is there any way for reusing the original method.

Controller: Similar methods but I need to have different promises.

$scope.applyReportFilter = function(){
    $log.log($scope.period);
    $scope.periodData = {periodType:$scope.period.id};
    var promisT = rptSvc.getAllReportE($scope.periodData);
    promisT.then(function(resultW){
        $scope.resultReport = resultW;
        $log.log("Rpt filter" + resultW);
    }).then(function(errorT){
        $scope.result = errorT;
    });
}
var promis = rptSvc.getAllReport($scope.periodData);
    //$log.log($scope.data.period);
    promis.then(function(result){
        $scope.resultReport = result;
        $log.log("Rpt" + result);
    }).then(function(error){
        $scope.result = error;
    });

Service: For applying filter I had to use another method to have different deferred.

var dfrdE = $q.defer();
report.getAllReportE=function(prd){
    $log.log(prd.periodType);
    $http.post(URLs.AllReportURL,prd)
    .success(function(respE){
        dfrdE.resolve(respE);
    }).error(function(respE){
        dfrdE.reject(respE);
    });

    return dfrdE.promise;
}
var dfrd = $q.defer();
report.getAllReport=function(prd){
    $log.log(prd.periodType);
    $http.post(URLs.AllReportURL,prd)
    .success(function(respGR){
        dfrd.resolve(respGR);
    }).error(function(respGR){
        dfrd.reject(respGR);
    });

    return dfrd.promise;
}

Any suggestion would be really helpful.


Solution

  • You have managed to do two Promise anti-patterns in your code.

    • $http returns a $q promise in itself, you are just wrapping it up in another promise.
    • When needed, use $q(.. instead of $q.defer because the revealing constructor pattern has a nicer, conciser syntax (doesn't need an extra deferred variable) and also catches exceptions from the resolver callback. .

    I do not exactly understand what you are trying to convey in second part of question, but you can reduce both service calls to simply be:

    report.getAllReport=function(prd){
        $log.log(prd.periodType);
        return $http.post(URLs.AllReportURL,prd);
    }