0

I have an $http.post call like this:

$scope.calcBarCost = function(bar, SAC, fieldSpeed) {
  console.log('bar cost details', bar);
  console.log('SAC', SAC);
  console.log('FIELD SPEED', fieldSpeed);
  data = {
    SAC: SAC,
    access_token: $scope.userData.access_token,
    fieldSpeed: fieldSpeed
  };


  var barCost = 0;
  return $http.post(apiPath + 'grabFieldLabor.php', data)
  .success(function(response) {
    var fieldLabor = 1000;

    if(response.fieldLabor) {

      console.log('Grab Field Labor Response', response);

      // After we get the field labor then we can run the calculations
      fieldLabor = parseFloat(response.fieldLabor);
      console.log('FINAL FIELD LABOR', fieldLabor);
      var averageCostPerHour = num($scope.userData.averageIronWorkersCost);

      barCost = (bar.weight / (fieldLabor / 8)) * averageCostPerHour

      var gradeCost = num($scope.costFactors[bar.grade]) * bar.weight;
      var bendCost = num($scope.costFactors[bar.bend]) * bar.weight;

      // Increased Cost Considerations
      var cf = numberize($scope.costFactors);
      var increasedCostConsiderations = 0;
          increasedCostConsiderations += (percent(cf.weather) * barCost) + (percent(cf.difficultWorkspace) * barCost) + (percent(cf.materialLifting) * barCost) + (percent(cf.jobSiteInterferences) * barCost) + (percent(cf.naturalDisasters) * barCost) + (percent(cf.difficultCircumstances) * barCost);

      barCost += gradeCost + bendCost + increasedCostConsiderations;

    }

    console.log('Final Bar Cost', barCost);

    return barCost;
  });

}

I'm trying to return a calculation that happens after the data is retrieved, but the data isn't returning. What am I doing wrong?

Jordash
  • 2,926
  • 8
  • 38
  • 77

3 Answers3

2

When you return $http.post, you actually return a promise and not the return value from within the .success or .then functions.

Rather than

return barCost; 

... set barCost in the parent scope.

EDIT:

Option 1 (Promises):

function doSomePromiseRequests() {
    return $http.post(...);
}

function parentFunction(){
    doSomePromiseRequests().then(success, error);
}

function success(data) {
    ....
}

function error(data) {
    ....
}

Option 2 (Callbacks):

function doSomeRequest(callback) {
    $http.post(...).then(function(success){
        callback(success, null);
    }, function(error){
        callback(null, error);
    });
}

function parentFunction(){
    doSomeRequest(function(success, error){
       ...
    });
}

EDIT (After you expanded on your question):

Function to run from your view / controller: calculateBarCost.
$scope.calcBarCost is updated on the view after $http request is made.

$scope.calculateBarCost = function(bar, SAC, fieldSpeed) {

  ...

  $http.post(apiPath + 'grabFieldLabor.php', data)
  .success(function(response) {
     ....

    $scope.calcBarCost = barCost;
  });

}
0

The .success method (deprecated and now removed from AngularJS 1.6) ignores return values. On the otherhand, the .then method uses returned values to create a new derived promise that resolves to the value returned.

$scope.calcBarCost = function(bar, SAC, fieldSpeed) {
  console.log('bar cost details', bar);
  console.log('SAC', SAC);
  console.log('FIELD SPEED', fieldSpeed);
  data = {
    SAC: SAC,
    access_token: $scope.userData.access_token,
    fieldSpeed: fieldSpeed
  };


  //var barCost = 0;
  return $http.post(apiPath + 'grabFieldLabor.php', data)
  //.success(function(response) {
  //USE then method
  .then(function(response) {
    var data = response.data;
    var barCost;

    var fieldLabor = 1000;

    //...
    //Use data variable to calculate barCost
    //...    

    console.log('Final Bar Cost', barCost);

    return barCost;
  });

}

USAGE:

var barCostPromise = $scope.calcBarCost(bar, SAC, fieldSpeed);

barCostPromise
  .then( function(barCost) {
    console.log(barCost);
}).catch( function(errorResponse) {
    console.log(errorResponse.status);
});

how do you return the values though? This needs to be run several times in a loop

JavaScript is single-threaded. A function can only return a value that is immediately available or a pending promise that is later fulfilled with a value from the server (or calculated from a value returned from a server).

Subsequent calculations can be done by furnishing a function to the .then method of the promise. Functions furnished to the .then method are held by the $q Service until the data is available.

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • how do you return the values though? This needs to be run several times in a loop – Jordash Feb 07 '17 at 20:17
  • When you say, "this needs to be run several times in a loop", do you mean the calculation needs several XHR POST operations? Or do you mean something else? – georgeawg Feb 07 '17 at 20:37
  • $scope.calcBarCost() is run several times in a loop and it needs to return a value every time, right now I can't get it to return anything except for undefined – Jordash Feb 07 '17 at 20:39
  • The code as written, returns an httpPromise unless it is AngularJS v1.6 in which case there should be a runtime error message in the console because the `.success` method has been removed. – georgeawg Feb 07 '17 at 20:43
0

You should place the promise-function .success() in your controller. Something like:

    angular.module('app').controller('myController', ['$scope','myService',function($scope, myService){

      $scope.barCost = 0;

      function makeHttpPost() {
      //Here we call the $http.post function which is hypothetically created in 'myService'

      myService().then(success, fail);

      function success(resp) {
      //Do whatever calculations I have to do and assign the result on $scope.barCost.

    }

    function fail(resp) {
      //Handle Errors
    }
}      

    }])
korteee
  • 2,640
  • 2
  • 18
  • 24