Domanda

few days ago I posted a question on how to do a Chart with AngularJS of a sharepoint list, here's the link.
Now I have a more complicated one: how to make a chart with multiple lists? I'm using AngularJS and angular-chart.js

As I'm very new working with code (I'm no developer), I find it a little difficult to understand some things about this. I've found some coding on how to make a controller with multiple $http calls, like here.

Now my problem: I need to count the number of Items of each list and how many of these items have Status=="Completed". So I want to be able to make multiple $http requests in a single controller. Based on the code of the link I mentioned before, I made this:

<!DOCTYPE html>
<html>
<head>
    <script src="jquery-2.1.4.min.js"></script>
    <script src="angular.js"></script>
    <script src="Chart.js"></script>
    <script src="angular-chart.min.js"></script>
    <script>
        var spApp = angular.module("spApp", ["chart.js"]);
        //I created a Factory to call the different lists
        spApp.factory("myLists", function($http) {
            return {
                americaTracker: function() {
                    return $http.get("SiteURL/_api/web/lists/getByTitle('America List')/items");
                },
                europeTracker: function() {
                    return $http.get("SiteURL/_api/web/lists/getByTitle('Europe List')/items");
                },
                asiaTracker: function() {
                    return $http.get("SiteURL/_api/web/lists/getByTitle('Asia List')/items");
                },
               //This last one is a list where I write the names of the previous task lists
                listSummary: function() {
                    return $http.get("SiteURL/_api/web/lists/getByTitle('Lists Summary')/items");
                }
            }
        });

        spApp.controller("BarCtrl", function(myLists, $scope) {
            //each of these functions are supposed to count how many items the list have, and how many of those have Status "completed":
            function americaTracker() {
                var promise = myLists.americaTracker();
                promise.then (
                    function(response) {
                        $scope.dataResults = response.data;
                        var items = $scope.dataResults,
                            ameItems = 0,
                            ameCompleted = 0;
                        for(var i = 0 ; i< items.length; i++){
                            ameItems++;
                            var currentItem = items[i];
                            if(currentItem.Status=="Completed"){
                                ameCompleted++;
                            }
                        };
                        return {
                           ameItems: ameItems,
                           ameCompleted: ameCompleted
                        }
                    }
                );
            }

            function europeTracker() {
                var promise = myLists.europeTracker();
                promise.then (
                    function(response) {
                        $scope.dataResults = response.data;
                        var items = $scope.dataResults,
                            eurItems = 0,
                            eurCompleted = 0;
                        for(var i = 0 ; i< items.length; i++){
                            eurItems++;
                            var currentItem = items[i];
                            if(currentItem.Status=="Completed"){
                                eurCompleted++;
                            }
                        };
                        return {
                           eurItems: eurItems,
                           eurCompleted: eurCompleted
                        }
                    }
                );
            }

            function asiaTracker() {
                var promise = myLists.asiaTracker();
                promise.then (
                    function(response) {
                        $scope.dataResults = response.data;
                        var items = $scope.dataResults,
                            asiItems = 0,
                            asiCompleted = 0;
                        for(var i = 0 ; i< items.length; i++){
                            asiItems++;
                            var currentItem = items[i];
                            if(currentItem.Status=="Completed"){
                                asiCompleted++;
                            }
                        };
                        return {
                           asiItems: asiItems,
                           asiCompleted: asiCompleted
                        }
                    }
                );
            }

            //this function is supposed to collect the names of each item (which are the names of the other three lists)
            function listSummary() {
                var promise = myLists.listSummary();
                promise.then (
                    function(response) {
                        $scope.dataResults = response.data;
                        var items = $scope.dataResults, arrayLabels = [];
                        for(var i = 0 ; i< items.length; i++){
                            var currentItem = items[i];
                            arrayLabels.push(currentItem.LinkTitle);
                        };
                        return arrayLabels;
                    }
                )
            }

            //Here I'm trying to call the functions by their specific value: the number of items and the items with status "completed"
            var ameList = americaTracker(),
                eurList = europeTracker(),
                asiList = asiaTracker(),
                listSum = listSummary();

            $scope.labels = listSum.arrayLabels;
            $scope.series = ['Items', 'Items Completed'];
            $scope.data = [
                [ameList.ameItems, eurList.eurItems, asiList.asiItems],
                [ameList.ameCompleted, eurList.eurCompleted, asiList.asiCompleted]
            ]
        });
    </script>
</head>
<body>
    <div ng-app="spApp" ng-controller="BarCtrl">
        <canvas id="bar" class="chart chart-bar"
                chart-data="data" chart-labels="labels" chart-series="series">
        </canvas>
    </div>
</body>
</html>

The error the console is giving me is Cannot read property 'arrayLabels' of undefined. But the thing is I don't really know how to do this, specially the call of multiple https.
I've been a lot of time doing this, I need help. Thanks!

P.D. Also I don't know if I have to call $scope.dataResults = data.d.results;. That's how I usually call the data.

È stato utile?

Soluzione

I found out the solution (after almost 2 months, I was kinda busy).
I decided to use $q.all to make the requests, this is a simpler solution instead of "promises" (which I wasn't very sure how it works):

<!DOCTYPE html>
<html>
<head>
<script src="jquery-2.1.4.min.js"></script>
<script src="angular.js"></script>
<script src="Chart.js"></script>
<script src="angular-chart.min.js"></script>
<script>
    var spApp = angular.module("spApp", ["chart.js"]);
    spApp.factory("myLists", ["$http", function($http) {
        return {
            americaTracker: function() {
                //I decided to use the "traditional" way to call each list:
                return $http({
                    method: "GET",
                    url: "siteURL/_api/web/lists/getByTitle('America List')/items",
                    headers: {"Accept": "application/json; odata=verbose"}
                });
            },
            europeTracker: function() {
                return $http({
                    method: "GET",
                    url: "siteURL/_api/web/lists/getByTitle('Europe List')/items",
                    headers: {"Accept": "application/json; odata=verbose"}
                });
            },
            asiaTracker: function() {
                return $http({
                    method: "GET",
                    url: "siteURL/_api/web/lists/getByTitle('Asia List')/items",
                    headers: {"Accept": "application/json; odata=verbose"}
                });
            },
            listSummary: function() {
                return $http({
                    method: "GET",
                    url: "siteURL/_api/web/lists/getByTitle('Lists Summary')/items",
                    headers: {"Accept": "application/json; odata=verbose"}
                });
            }
        }
    }]);

    //I'm using $q.all to call each list data
    spApp.controller("BarCtrl", function($scope, $http, myLists, $q) {
        $q.all([
            myLists.americaTracker().then(function onSuccess(response) {
                var items = response.data.d.results,
                    totalItems = 0,
                    itemCompleted = 0;
                for (var i=0;i<items.length;i++) {
                    totalItems++;
                    var currentItem = items[i];
                    if(currentItem.Status=="Completed"){
                        itemCompleted++;
                    }
                };
                $scope.ameItems = totalItems;
                $scope.ameComp = itemCompleted;
            }),
            myLists.europeTracker().then(function onSuccess(response) {
                //I'm using the same names for these variables, as they are all local
                var items = response.data.d.results,
                    totalItems = 0,
                    itemCompleted = 0;
                for (var i=0;i<items.length;i++) {
                    totalItems++;
                    var currentItem = items[i];
                    if(currentItem.Status=="Completed"){
                        itemCompleted++;
                    }
                };
                $scope.eurItems = totalItems;
                $scope.eurComp = itemCompleted;
            }),
            myLists.asiaTracker().then(function onSuccess(response) {
                var items = response.data.d.results,
                    totalItems = 0,
                    itemCompleted = 0;
                for (var i=0;i<items.length;i++) {
                    totalItems++;
                    var currentItem = items[i];
                    if(currentItem.Status=="Completed"){
                        itemCompleted++;
                    }
                };
                $scope.asiItems = totalItems;
                $scope.asiComp = itemCompleted;
            }),
            myLists.listSummary().then(function onSuccess(response) {
                var items = response.data.d.results,
                    arrayLabels = [];
                for (var i=0;i<items.length;i++) {
                    var currentItem = items[i];
                    arrayLabels.push(currentItem.LinkTitle);
                };
                $scope.labels = arrayLabels;
            })
        ]).then(function() {
            //Here I call the values for each $scope object
            //except "labels" which was already defined in "listSummary()"
            $scope.series = ['Items', 'Items Completed'];
            $scope.data = [
                [$scope.ameItems, $scope.eurItems, $scope.asiItems],
                [$scope.ameComp, $scope.eurComp, $scope.asiComp]
            ];

        });
    });
</script>
</head>
<body>
<div ng-app="spApp" ng-controller="BarCtrl">
    <canvas id="bar" class="chart chart-bar"
            chart-data="data" chart-labels="labels" chart-series="series">
    </canvas>
</div>
</body>
</html>

Altri suggerimenti

You are trying to use listSum.arrayLabels but what you have done in your code in function listSummary() is returned arrayLabels. So, as per your code, listSum = arrayLabels (listSum is nothing but arrayLabels). So you can directly try using listSum as given below:

$scope.labels = listSum;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a sharepoint.stackexchange
scroll top