javascriptangularjsangularjs-scopeangular-promiseangularjs-q

unable to use $q and promise


I want to use the variable StatusASof to display data in the inserthtml function as below.

App.controller("SS_Ctrl", function ($scope, $http, $location, $window, $sce, $q) {

var ShiftDetails = []; 

   function getMAStatusASof(Id) {
        var defer = $q.defer();
        $http({
            method: 'GET',
            url: 'http://xx/api/Sxxx/GetMAStatusASof',
            params: { Id: Id }        
        }).then(function successCallback(response) {            
            StatusASof = response.data;           
            alert("getMAStatusASof : " + StatusASof);  --> Got data from API here in this alert.
            defer.resolve(response);
        }, function errorCallback(response) {});
    }

 function insertHtml(dates, ShiftDetails, Id) {

       // var promise = getMAStatusASof(Id); promise.then(

        var defer = $q.defer();
        getMAStatusASof(Id); 
    alert(StatusASof);  --> alert says empty here
    defer.resolve();       
        var Content;
        Content = '<table class="clsTable">  <tr>  <td rowspan="2">Cases ' + $scope.StatusASof + ' </td>  <td rowspan="2">Total</td> ';
        for (var i = 0; i <= 6; i++) {
            if (i == daySeq - 1) {            
                Content = Content + '<td colspan="3"  style="background-color:red"> {{dates[ ' + i + ']}} </td> ';
            }           
        }
}

but $scope.StatusASof is undefined while displaying the result. Looks like $q.defer is not working for me.

How can I continue the execution of code after getting data only from the getMAStatusASof(Id);

Can somebody help here.


Solution

  • No need to use $q.defer() here...

    Just do

    function getMAStatusASof(Id) {
      return $http({
        method: 'GET',
        url: 'http://xx/api/Sxxx/GetMAStatusASof',
        params: { Id: Id }        
      })
      .then(function successCallback(response) {     
        return response.data;
      })
      .catch(function errorCallback(response) {
        return null;  //Effectively swallow the error an return null instead.
      });
    }

    Then, use

    getMAStatusASof(Id).then(function(result) {
      console.log(result);
    });
    //No .catch, as we've caught all possible errors in the getMAStatusASof function

    If you really would like to use $q.defer(), then the function would need to return defer.promise, like Jazib mentioned.

    But as I said, since $http already returns a promise, doing the whole $q.defer() + return defer.promise thing is superfluous.

    Instead, use that construction only when the thing you need to wrap isn't returning a promise on its own. E.g when you open a bootbox modal and want to be informed of when the user clicked the close button

    function notifyMeOfClosing() {
      var deferred = $q.defer();
      bootbox.confirm("This is the default confirm!", function(result){ 
        if(result) {
          deferred.resolve();
        }
        else {
          deferred.reject();
        }
      });
      return deferred.promise;
    }