Tips on combining $scope object values within AngularJS

I am extracting data from various SharePoint pages lists by utilizing a Factory.
Within my code, I am determining the number of items with a "Completed" status in each list.
I am attempting to store these values in an array, but it consistently returns null.
Take a look at this 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>

When attempting to display the values individually, they are correct! However, when trying to insert them into an array, they show as "null":

3
5
[null, null]

Why is this occurring and what steps can I take to resolve it? Could there be something incorrect in my approach?

CODE UPDATE
Below is the updated working code based on suggestions from Sergey Mell and using $q, also leveraging AngularJS v1.7.5 (as recommended by georgeawg):

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));
            });
        });

Answer №1

To ensure that your data is retrieved only after both requests are completed, it is important to wait until all promises have resolved. One effective way to achieve this in AngularJS is by using Promise.all or $q.all. Here's an example implementation:

myApp.controller("myController", function($scope, $http, myFactory, $q) {
        $q.all([
           myFactory.siteOne().then(/* Add your logic here */), 
           myFactory.siteTwo().then(/* Add your logic here */), 
        ]).then(function() {
           $scope.data = [
             $scope.oneItems, $scope.twoItems
           ];
        })

Answer №2

Assign values to specific keys as follows:

$scope.data = [
keyOne: $scope.oneItems, 
keyTwo: $scope.twoItems ];

Answer №3

If you're looking for a solid solution, consider following Sergey Mell's advice and make use of the $q service.
If using $q isn't an option: declare $scope.data = []; at the beginning and then utilize
$scope.data.push($scope.oneItems)
Just ensure you initialized $scope.data to [] initially; otherwise, it will result in an error.
Your controller script will resemble:

  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));
    });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Production environment experiences issues with Angular animations

In my MEAN stack application, I started with Sails.js. Everything was working smoothly during development, especially with angular-animate. However, once I changed the Sails environment to production, I encountered issues. Grunt is set up to concatenate a ...

How can I change an array to a string in JavaScript/jQuery and add a specific

Currently, I am tasked with the challenge of converting an array into objects. Furthermore, I also need to add something before each object is displayed. var arrayList = ["image1.jpg","image2.jpg","image3.jpg"]; The desired outcome should look like this ...

Import MDX metadata in Next.js on the fly

I am currently utilizing Next.js to create a static blog site. Following the guidelines in Next.js documentation, I set up @next/mdx and successfully imported MDX statically using import MDXArticle from "@/app/(article)/2023/test-article/page.mdx&quo ...

How can I capture the ng-click event in AngularJS when using bootstrap-select for styled select inputs?

After selecting an option, I am facing an issue where I cannot capture the ng-click event when a user chooses a value from the drop-down menu. This is because the select option has been altered by bootstrap-select, as the default select option does not sup ...

Database Migration ObjectId Problem

I am currently utilizing db-migrate and looking for a way to insert documents into a MongoDB collection with specific fields requiring the use of ObjectId. However, I encountered an error indicating that ObjectId is not defined. [ERROR] AssertionError [ER ...

Is there a way to pre-format a phone number field using jQuery?

Looking to create a phone number text field with a pre-formatted 10-digit structure, like this: |( ) - | allowing users to input numbers and have them fill in automatically: |(804) 479-1832| I came across a helpful script for formatting input d ...

Utilizing logical operators to assign values to variables in Typescript

export class SearchResult { id: string; constructor(obj?: any) { this.id = obj && obj.id || null; } } Can someone explain to me the meaning of obj && obj.id || null? I'm confused by this syntax. ...

Creating compressed files using JavaScript

I am currently working on unzipping a file located in the directory "./Data/Engine/modules/xnc.zip" to the destination folder "./Data/Engine/modules/xnc". Once I have completed writing to these files, I will need an easy method to rezip them! While I wou ...

Looking to add a button on a PolymerJS page that will allow users to download a PDF file of the report in a row-by-row

I am looking to add a button to a polymerJS webpage that, when clicked, will download a PDF with decorations in a table format containing rows and columns. Can someone guide me on how to achieve this? Thank you in advance. ...

I'm interested in developing a React function that generates recipe components based on a set of instructions provided in an array, along with a separate parameter specifying the recipe name

I am currently immersed in the book "Learning React" written by O'Reilly. The book mentions a method of creating components by using a function known as the "component creating function". It advises supplying the necessary parameters as the second par ...

Checking for the existence of a variable retrieved from the API in AngularJS

On the api side, I am receiving a json metadata object with image properties. To test for the existence of a property, I am using angularJS, coffeescript, and haml for the views. Below is the JavaScript code that fetches the data: getImages = -> l ...

Updating an item stored locally

I am currently working on a web application that utilizes local storage. I have successfully implemented functionality to add and delete items, but I am facing an issue with editing items. Although items can be edited as expected, upon refreshing the page, ...

Setting the current date as the default in an input box using ng-it: a step-by-step guide

How do I automatically set today's date as the default in the input box using ng-it? Here is my Plunker I am simply looking to set today's date as the default in the input field using ng-it. Would appreciate it if you could check out my P ...

Combining the total of numerous inputs that are multiplied by a specific value all at once

Hey, I've been working on a project with a table and an input field with costs using jQuery. You can check out This Fiddle for reference. $( ".total" ).change(function() { let i = 1; var input001 = document.getElementsByName(i)[0]; var ...

Tips for adapting my custom input component for compatibility with vee-validate?

I recently developed an input component for my Vue project and integrated it within my forms. My aim is to implement vee-validate for validating the inputs. Initially, I attempted to validate my component like any regular input field. However, upon encoun ...

Is there a method to track the progress of webpage loading?

I am working on a website built with static HTML pages. My goal is to implement a full-screen loading status complete with a progress bar that indicates the page's load progress, including all images and external assets. Once the page has fully loaded ...

Performing inner joins on 2 tables using Mongoose

My inner join query seems to be resulting in a left join unexpectedly. I have 2 tables with relations and I'm trying to retrieve movies along with their genre names. Here are the models I'm working with: // Movie const MovieSchema = new mongoose ...

What causes ngClick to stop working following $compile?

http://plnkr.co/edit/kL2uLPQu2vHHKIvRuLPp?p=preview Upon button click, the controller calls a service to compile HTML and inject it into the body. The compiled HTML (displaying "Hello World" from $scope.name) is referring to the scope of the controller, ...

Angular and Django Rest Framework working in perfect synchronization

My Django rest framework powered API utilizes the default pagination feature, as shown below: { "count": 40, "next": "http://127.0.0.1:8000/api/task/?page=2", "previous": null, "results": [{},{}...] } On the Angular side, I am using ng ...

When using jQuery's .each method, only the final JavaScript object element is added to the divs

I have a unique set of dynamically-created divs, each containing a Title. When a div is clicked, a modal opens (which is cleared upon click), and the Title is displayed again in the modal. My goal is to add the category descriptions into these modals, but ...