Search code examples
javascriptangularjscordova-plugins

Confusion about Javascript 'then' behaviour


I have the following code in an Angular controller...

function doWork() {
  // show the loading modal
  $scope.modal = $ionicLoading.show({
    content: 'Fetching current location...',
    showBackdrop: false
  });

  console.log("get orig pos");

  // get the position
  PositionService.getPosition(posOptions)
    .then(function(positionArr) {
      // got 1st location // this doesn't execute!
      console.log("got original pos: " + positionArr.length);          
      $scope.locationArray = positionArr;
      $scope.dataReceived = true;
      $scope.modal.hide();
    }, function(err) {
      // something went wrong
      console.log("something wrong in getPos");
      $timeout(function() {
        $scope.modal.hide();
      }, 3000);          
    });

    console.log("get next pos");

  PositionService.getPosition(posOptions)
    .then(function(positionArr) {
      // got 2nd location // this does execute!
      console.log("got new pos: " + positionArr.length);          
      $scope.locationArray = positionArr;
      $scope.dataReceived = true;
    }, function(err) {
      // something went wrong
      console.log("something wrong in getPos");
    });
 }

When I run the program the PositionService.getPosition function is invoked twice, as I would expect, but only one of the then parts is executed. Shouldn't both of the then blocks be executed or am I misunderstanding how this works in Javascript? This is the content of the getPosition function...

   getPosition : function(posOptions) {
      return $cordovaGeolocation
        .getCurrentPosition(posOptions)
        .then(function(position) {
          positionArr = positionArr.concat({
            position: position,
            status: 'new'
          });
          return positionArr;
        }, function(err) {
          console.log("PositionService: error getting position");
          return err;
        });
    },

EDIT:

Here is the console output as requested...

image


Solution

  • You should be chaining your calls to the position service:

    var p1 =  PositionService.getPosition(posOptions)
        .then(function(positionArr) {
          // got 1st location
          console.log("got original pos: " + positionArr.length);          
          $scope.locationArray = positionArr;
          $scope.dataReceived = true;
          $scope.modal.hide();
        }, function(err) {
          // something went wrong
          console.log("something wrong in getPos");
          $timeout(function() {
            $scope.modal.hide();
          }, 3000);          
        });
    
    var p2 = p1.then (function() {
         return PositionService.getPosition(posOptions);
       }).then(function(positionArr) {
          // got 2nd location
          console.log("got new pos: " + positionArr.length);          
          $scope.locationArray = positionArr;
          $scope.dataReceived = true;
        }, function(err) {
          // something went wrong
          console.log("something wrong in getPos");
        });