0

This is my first angularjs application that I am updating but not working well. Basically i have a spinner that I need to show when calculating then turn it off. My promises are resolving well but the component does not pick up the new value. If I click a button that actually changes the loading variable, it does work in that the component picks up the false value.

But I want it to be turned off once the promise is complete. It does resolve and I do reach the vm.loading = false value well but the component don't get that new value.

(function () {

    var app = angular.module('APP').controller('APPController',
    ['$q', '$scope', '$http', '$timeout', '$location', '$filter', 'dataservice', '$routeParams', controller]);

    function controller($q, $scope, $http, $timeout, $location, $filter, dataservice, $routeParams) {

        // The controller's API to which the view binds
        var vm = this;
        vm.loading = false;
        vm.data = null; // GET THIS FROM API
        getSettings();

        function getSettings() {

            vm.loading = true;

            var pArray = []; // promises Array
            var p1 = vm.ds.fetchExstingSettings(10);
            pArray.push(p1);

            $q.all(pArray)
                .then(function (data) {
                    // get api data now    
                    fetchData().then(done => {
                        vm.loading = false; // reaching here well
                    })    
                })
                .catch(
                function (err) {
                    alert(err);
                    return null;
                })
                .finally(function () {    
                    $timeout(function () {
                        vm.searchLoading = 0;
                        $scope.$apply();
                    });
                });
        }


      async function fetchData() {    
          var result = await $http.get('http://localhost:4228/Api/data');
          vm.data = result;             
      }    
      function saveChanges() {
          vm.loading = false; // this works     
      }    
    }
})();// JavaScript source code

html:

<div class="text-center" ng-if="vm.loading == true">
    <i class="fa fa-spin fa-spinner fa-5x"></i>
</div>
georgeawg
  • 48,608
  • 13
  • 72
  • 95
Wede Asmera Tseada
  • 513
  • 2
  • 4
  • 14
  • 1
    The ES6 promises used by `async / await` are not integrated with the AngularJS framework and its execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc. – georgeawg Nov 07 '19 at 16:16
  • use $scope.$apply() inside the async function to trigger angularjs to take the changes into account – Pierre Emmanuel Lallemant Nov 07 '19 at 16:29

1 Answers1

1

The ES6 promises used by async / await are not integrated with the AngularJS framework and its execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

One approach is to wrap the ES6 promise in $q.when:

  $q.all(pArray)
    .then(function (data) {
        // get api data now    
        $q.when(fetchData()).then(done => {
            vm.loading = false; // reaching here well
        })    
  })

From the Docs:

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

For more information, see

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95