user7157121
user7157121

Reputation: 57

sequential execution in angularjs controller

I have method in angular controller which call service; this method should act based on the service response.

but I don't know why the method call in the right time.

$scope.UpdateSelected = function () {
    $rootScope.showConfirmModal().result.then(function () {
        var selectedItems = _.filter($scope.Options, { Selected: true });
        var error = 0

        for (var i = 0 ; i < selectedItems.length; i++) {
            InvalidOptionsFactory.UpdateOptions(selectedItems[i].Id).then(function (res) {
                if (res.data.error) {
                    error++;
                }
            });
        }
            if (error == 0) {
                toastr.success($rootScope.GetString('GENERIC_SAVE_SUCCSS_MSG'));
            }

            else if (error == selectedItems.length) {
                $rootScope.showMessageModal($rootScope.GetString('UPDATE_STATUS_FAILED'), 'sm');
            }
            else {
                var message = hasError + $rootScope.GetString('UPDATE_STATUS_PARTIALLY_FAILED');
                toastr.success(message);
            }
            fetchSearchedData();
    });
    };

I don't now why it's directly go to if statement and execute it then call the service

Upvotes: 0

Views: 836

Answers (1)

samAlvin
samAlvin

Reputation: 1678

It is because InvalidOptionsFactory.UpdateOptions(selectedItems[i].Id) method is asynchronous. That's what makes the app doesn't wait for the service to call, it run the if (error == 0) statements first instead (See below snippet for proof). Learn asynchronous method here: https://www.pluralsight.com/guides/front-end-javascript/introduction-to-asynchronous-javascript

You can make your code into something like this (p.s. I used babel as the prepocessor):

$scope.UpdateSelected = function () {
  $rootScope.showConfirmModal().result.then(function () {
    var selectedItems = _.filter($scope.Options, { Selected: true });
    checkForError(selectedItems).then(error => {
      if (error == 0) {
        toastr.success($rootScope.GetString('GENERIC_SAVE_SUCCSS_MSG'));
      } else if (error == selectedItems.length) {
        $rootScope.showMessageModal($rootScope.GetString('UPDATE_STATUS_FAILED'), 'sm');
      } else {
        var message = hasError + $rootScope.GetString('UPDATE_STATUS_PARTIALLY_FAILED');
        toastr.success(message);
      };

      fetchSearchedData();
    });
  });
};

function checkForError(selectedItems): Promise<number> {
  return new Promise(resolve => {
    var error = 0;
    for (var i = 0 ; i < selectedItems.length; i++) {
      InvalidOptionsFactory.UpdateOptions(selectedItems[i].Id).then(function (res) {
        if (res.data.error) {
          error++;
        };
      });
    };

    resolve(error); 
  });
}

function asyncFunc(): Promise<void> {
  return new Promise(resolve => {
    console.log("this is async");
    resolve();
  });
}

asyncFunc().then(() => {
  console.log("async function ended");
});

console.log("this will be called before async function ended");

Upvotes: 1

Related Questions