简体   繁体   中英

Why the promise doesn't work when outside of the loop?

I'm trying to dynamically add fusionCharts into the AngularJS page. I'm loading charts data into model object, the charts object does display, but with "No data to display" content.

My app.js:

(function () {

var modelListOfCharts = ["1", "4", "5", "6"];
var model = {};
var app = angular.module('chartDash', ["ng-fusioncharts"]);

app.controller('fussionController',["$scope","DataService", function ($scope, DataService) {
    $scope.chartData = {};

    DataService.getThings().then(function () {
        $scope.myListOfCharts = modelListOfCharts;
        $scope.chartData = model;
    });
}]);

app.service("DataService", ["$http", "$timeout", "$q", function ($http, $timeout, $q) {
    return {
        getThings: function () {
            var dfd = $q.defer();
            $timeout(function () {
                angular.forEach(modelListOfCharts, function(chartId) {
                    $http.get('/FusionCharts/GetChartData/', { params: { chartID: chartId } }).success(function (result) {
                        model[chartId] = result;
                    });
                });
                dfd.resolve(model);
            }, 300);
            return dfd.promise;
        }
    };
}]);
})();

My html:

<div ng-controller="fussionController">
    <div ng-repeat="n in myListOfCharts">
        <h2>Chart number {{n}}</h2>
        <fusioncharts width="100%"
                      height="400"
                      type="MSCombi2D"
                      datasource="{{chartData[n]}}"></fusioncharts>
    </div>
</div>

When I put dfd.resolve(model); inside the loop it works but only displays data for one chart.

    app.service("DataService", ["$http", "$timeout", "$q", function ($http, $timeout, $q) {
    return {
        getThings: function () {
            var dfd = $q.defer();
            $timeout(function () {
                angular.forEach(modelListOfCharts, function(chartId) {
                    $http.get('/FusionCharts/GetChartData/', { params: { chartID: chartId } }).success(function (result) {
                        model[chartId] = result;
                        dfd.resolve(model);
                    });
                });

            }, 300);
            return dfd.promise;
        }
    };
}]);

Since there are multiple http gets there will be multiple promises. So you have to wait for all those promises to be resolved. Try this.

app.service("DataService", ["$http", "$timeout", "$q", function ($http, $timeout, $q) {
    return {
        getThings: function () {
            var arrayOfPromises = [];
                angular.forEach(modelListOfCharts, function(chartId) {
                    arrayOfPromises.push($http.get('/FusionCharts/GetChartData/', { params: { chartID: chartId } }).success(function (result) {
                        model[chartId] = result;
                    }));
                 });

            return $q.all(arrayOfPromises);
        }
    };
}]);

You need to create a promise for each chart and then wait for them all to resolve:

app.service("DataService", ["$http", "$timeout", "$q",
  function($http, $timeout, $q) {
    return {
      getThings: function() {
        var promises;

        $timeout(function() {
          promises = modelListOfChart.map(function(chartId) {
            var dfd = $q.defer();
            $http.get('/FusionCharts/GetChartData/', {
              params: {
                chartID: chartId
              }
            }).success(function(result) {
              model[chartId] = result;
              dfd.resolve(model);
            });
            // Might want to add a reject for errors...

            return dfd;
          });
        }, 300);

        return $q.all(promises);
      }
    };
  }
]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM