1

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.

2

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>
0

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;
  • Ok, I think that worked, but don't know what I did wrong with the others.. now it is telling me Cannot read property 'ameItems' of undefined – Soul Eeater Nov 18 '18 at 6:17
  • Put a debugger at this line: $scope.labels = listSum; and then check if ameList has some value. – harshal gite Nov 18 '18 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.