0

I'm taking the data from different sharepoint pages lists. I'm calling these lists with a Factory.
My code is counting how many items with a "Completed" status each list has.
I need to take the values of each one into an array, but the result is always null.
Here's my example:

    <script>
        var myApp = angular.module("myApp", []);
        myApp.factory("myFactory", ["$http", function($http) {
            return {
                siteOne: function() {
                    return $http({
                        method: "GET",
                        url: "siteURL/_api/web/lists/getByTitle('List 1')/items",
                        headers: {"Accept": "application/json; odata=verbose"}
                    });
                },
                siteTwo: function() {
                    return $http({
                        method: "GET",
                        url: "siteURL/_api/web/lists/getByTitle('List 2')/items",
                        headers: {"Accept": "application/json; odata=verbose"}
                    });
                }
            }
        }]);
        myApp.controller("myController", function($scope, $http, myFactory) {
            myFactory.siteOne().success(function(data, status, headers, config) {
                $scope.projects = data.d.results;
                var items = $scope.projects,
                    totalItems = 0;

                for (var i=0;i<items.length;i++) {
                    var currentItem = items[i];
                    if(currentItem.Status!="Completed") {
                        totalItems++;
                    }
                };
                $scope.oneItems = totalItems;
            });

            myFactory.siteTwo().success(function(data, status, headers, config) {
                $scope.projects = data.d.results;
                var items = $scope.projects,
                    totalItems = 0;

                for (var i=0;i<items.length;i++) {
                    var currentItem = items[i];
                    if(currentItem.Status!="Completed") {
                        totalItems++;
                    }
                };  
                $scope.twoItems = totalItems;
            });

            $scope.data = [
                $scope.oneItems, $scope.twoItems
            ];

            console.log(JSON.stringify($scope.oneItems));
            console.log(JSON.stringify($scope.twoItems));
            console.log(JSON.stringify($scope.data));
        });
    </script>

If I want to print each value separately, it shows the values! But if I try to put them inside the array, it shows the values as "null":

3
5
[null, null]

Why is this happening and how can I fix this? ..am I doing something wrong?

CODE UPDATE
Here is my code already working for those who'd like to see it. I changed the controller as Sergey Mell sugested, using $q, also I'm using AngularJS v1.7.5 (as georgeawg sugested):

myApp.controller("myController", function($scope, $http, myFactory, $q) {

            $q.all([
                myFactory.siteOne().then(response => {
                    var items = response.data.d.results,
                        totalItems = 0;

                    for (var i=0;i<items.length;i++) {
                        var currentItem = items[i];
                        if(currentItem.Status!="Completed") {
                            totalItems++;
                        }
                    };
                    $scope.oneItems = totalItems;
                }),
                myFactory.siteTwo().then(response => {
                    var items = response.data.d.results,
                        totalItems = 0;

                    for (var i=0;i<items.length;i++) {
                        var currentItem = items[i];
                        if(currentItem.Status!="Completed") {
                            totalItems++;
                        }
                    };  
                    $scope.twoItems = totalItems;
                })
            ]).then(function() {
                $scope.data = [
                    $scope.oneItems, $scope.twoItems
                ];

                console.log(JSON.stringify($scope.data));
            });
        });
Soul Eater
  • 505
  • 1
  • 7
  • 20
  • 1
    The `.success` method is deprecated. See [Why are AngularJS $http success/error methods deprecated? Removed from v1.6?](https://stackoverflow.com/questions/35329384/why-are-angularjs-http-success-error-methods-deprecated-removed-from-v1-6/35331339#35331339). – georgeawg Jan 02 '19 at 05:49
  • I didn't know that, I've been using Angular v1.3.0. Thank for that info @georgeawg – Soul Eater Jan 02 '19 at 23:07
  • Both the request to site1 and the the request to site2 put their data on the same $scope vaariable, `$scope.projects`. Is that intentional? – georgeawg Jan 03 '19 at 04:11
  • Yes, I made it intentional, but honestly I don't know why I did it.. right now it isn't giving me any problem but I've already modified it. I updated the code and is working. – Soul Eater Jan 03 '19 at 16:45
  • The `.then` method is available in AngularJS 1.3. In fact it has always been there. The `.success` method was created as a syntactic sugar but it is really a failure. It should be avoided in all new AngularJS code, including code intended for V1.3. V1.3 is no longer supported and using `.success` makes the migration path more difficult. – georgeawg Jan 03 '19 at 17:09

3 Answers3

1

You're putting your data before the requests have been finished. You have to wait till the end of both requests. I'd propose to use Promise.all or $q.all, which is more natural for AngularJS i.e.:

myApp.controller("myController", function($scope, $http, myFactory, $q) {
        $q.all([
           myFactory.siteOne().then(/* Your stuff here */), 
           myFactory.siteTwo().then(/* Your stuff here */), 
        ]).then(function() {
           $scope.data = [
             $scope.oneItems, $scope.twoItems
           ];
        })
Sergey Mell
  • 7,780
  • 1
  • 26
  • 50
  • 1
    `Promise.all` and `$.all` are not interchangeable. AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc. **Only `$q.all` executes in the AngularJS context.** – georgeawg Jan 03 '19 at 03:06
  • Good catch. Thank you for the qualification. – Sergey Mell Jan 03 '19 at 08:27
  • I didn't know about $q, and for some reason this is working! Now the values in the array doesn't appear as "null". Thanks a lot for your help. – Soul Eater Jan 03 '19 at 16:43
0

Also assign values to key like:

$scope.data = [
dataItemOne: $scope.oneItems, 
dataItemTwo: $scope.twoItems ];
Shujaat Ali
  • 81
  • 1
  • 5
-1

You have best option as @Sergey Mell given below use $q service.
If you don't want to use $q. then
Declare $scope.data = []; at top and use
$scope.data.push($scope.oneItems)
But make sure you have declared $scope.data to [] at the top otherwise it will throw error.
your controller code will be like

  myApp.controller("myController", function($scope, $http, myFactory) {
        $scope.data = [];
        myFactory.siteOne().success(function(data, status, headers, config) {
            $scope.projects = data.d.results;
            var items = $scope.projects,
                totalItems = 0;

            for (var i=0;i<items.length;i++) {
                var currentItem = items[i];
                if(currentItem.Status!="Completed") {
                    totalItems++;
                }
            };
            $scope.oneItems = totalItems;
           $scope.data.push($scope.oneItems);
        });

        myFactory.siteTwo().success(function(data, status, headers, config) {
            $scope.projects = data.d.results;
            var items = $scope.projects,
                totalItems = 0;

            for (var i=0;i<items.length;i++) {
                var currentItem = items[i];
                if(currentItem.Status!="Completed") {
                    totalItems++;
                }
            };  
            $scope.twoItems = totalItems;
             $scope.data.push($scope.twoItems );
        });

      /*  $scope.data = [
            $scope.oneItems, $scope.twoItems
        ];*/

        console.log(JSON.stringify($scope.oneItems));
        console.log(JSON.stringify($scope.twoItems));
        console.log(JSON.stringify($scope.data));
    });
Gitaram Kanawade
  • 341
  • 1
  • 4
  • 19