0

It's like there is a loading div that I want to show if two API calls are yet not ready with the results.

SO that the results all of sudden do not jump into the view causing it to flicker.

My view looks something like this :

<div ng-show="vm.loading" class="table-overlay table-overlay-loading">
    <div class="table-overlay-content">
        <div class="table-overlay-message">Loading&hellip;</div>
    </div>
</div>
<div ng-show="vm.loadError" class="table-overlay table-overlay-error">
    <div class="table-overlay-content">
        <div class="table-overlay-message"><i class="icon-error-indicator"></i>
            Error encountered. Please try again.
        </div>
    </div>
</div>
<div class="inner" ng-show="!vm.loading && !vm.loadError">
    <div class="info-panel">
        <h3>Current Pricing</h3>
        <p>
            Billing Period:
            <br>
            <em>{{vm.invoiceCoverageStartDate}} to {{vm.invoiceCoverageEndDate}}</em>
            <br>
            <big><b>${{vm.invoiceTotal}}</b>/month</big>
            <br>
            <a href=""><small>(See Details)</small></a>
        </p>
    </div>

And the methods to populate the interpolated values look like :

       vm.getCurrentPricingDetails = function(){
            HttpWrapper.send(url1, {"operation":'GET'})
            .then(function(result){
                console.log("Current Pricing Response: ", result);
                vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy");
                vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy");
                vm.invoiceTotal = result.invoice.invoiceTotal;
            }, function(error) {
                console.log("Error: Could not fetch current pricing details", error);
            });
        }


        vm.getProjectedPricing = function(){
            $timeout(function(){
                var selectedPricingMappingObj = dataStoreService.getItems('server');
                selectedPricingMappingObj.forEach(function(item){
                    vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost);
                });
                vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2);
            },1000);                                  
        }

But in my components $onInit method I tried to resolve the same using promise.

      vm.$onInit = function() {                
            vm.loading = true;
            vm.loadError = false;
            var currentPricingDetails = vm.getCurrentPricingDetails();
            var projectedPricingDetails = vm.getProjectedPricing();

            $q.all([currentPricingDetails,projectedPricingDetails]).then(function(results) {
                debugger;
                vm.loading = false;
            }, function(error){
                debugger;
                vm.loading = false;
                vm.loadError = true;
            });

But still the screen flickers and the loading div does not show .

I want the loading div to show until and unless the two method calls are not done with the results.`

How to achieve that ?

What am I doing wrong ?

StrugglingCoder
  • 4,781
  • 16
  • 69
  • 103
  • Either `getCurrentPricingDetails` and `getProjectedPricing` are not returning any promises so that the default `$q.all()` behavior is to consider the object resolved wheather it isn't a promise. – lenilsondc Feb 17 '17 at 13:24

2 Answers2

4

vm.getCurrentPricingDetails() and vm.getProjectedPricing() does not return anything. So your line

$q.all([currentPricingDetails,projectedPricingDetails])

is really just

$q.all([undefined, undefined])

$q.all expects an array of promises. $timeout returns a promise when it's done. And it seems like your HttpWrapper also returns a promise. So I think that all you need to do is to add returns to your code:

return HttpWrapper.send(url1, {"operation":'GET'})

and

return $timeout(function(){
HoffZ
  • 7,709
  • 6
  • 36
  • 40
2

vm.getCurrentPricingDetails and vm.getProjectedPricing are not returning promises and hence the $q.all has no chance knowing when they are finished

    m.getCurrentPricingDetails = function(){
        var defer = $q.defer();
        HttpWrapper.send(url1, {"operation":'GET'})
        .then(function(result){
            console.log("Current Pricing Response: ", result);
            vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy");
            vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy");
            vm.invoiceTotal = result.invoice.invoiceTotal;
           defer.resolve();
        }, function(error) {
            console.log("Error: Could not fetch current pricing details", error);
            defer.reject();
        });
        return defer.promise;
    }


    vm.getProjectedPricing = function(){
        var defer = $q.defer();
        $timeout(function(){
            var selectedPricingMappingObj = dataStoreService.getItems('server');
            selectedPricingMappingObj.forEach(function(item){
                vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost);
            });
            vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2);
            defer.resolve();
        },1000);   
        return defer.promise;                               
    }
Torben Pi Jensen
  • 850
  • 9
  • 27