The effectiveness of recursion in asynchronous function calls within AngularJS

My task involves creating a JSON output in tree structure from recursive async calls. The code I have developed for this purpose is detailed below:

$scope.processTree = function (mData, callback) {               
            _processTree.getWebCollection(mData.url).then(
                function(_rdata){
                       // transform xml -> json             
                        var x2js = new X2JS();
                        var json = x2js.xml_str2json(_rdata);
                        //console.log("XML DATA: " + _rdata);
                        //console.log("JSON DATA: " + JSON.stringify(json));
                        var _webs = json.Envelope.Body.GetWebCollectionResponse.GetWebCollectionResult.Webs.Web;

                        // if response has [] of webs - array of objects / sites
                        if ($(_webs).length > 0 && $.isArray(_webs)) {                                  
                            $.each(_webs, function (key) {
                                // loop and build tree
                                mData.children.push({                                           
                                    name: "Site: " + _webs[key]._Title,
                                    url: _webs[key]._Url,
                                    children: []
                                });                                     
                                // recursive loop call for each site again
                                    $scope.processTree(mData.children[key]);                                        
                            });                             
                        }
                        // if response has {} of webs - single object / site                    
                        else if ($.isPlainObject(_webs)) {                                  
                                mData.children.push({                                           
                                    name: _webs._Title,
                                    url: _webs._Url,
                                    children: []
                                });                             
                        }
                        // if no response or response is null, do nothing
                        else {  

                        }   
                }, function(msg){                       
                    alert("ERROR!!! \n\nERROR DATA: " + msg[0] + " \tStatus: " + msg[1]);
                });                 
    };

function callback(mData){
  // do something - use mData, create tree html and display
}

The recursion gathers all sites and subsites for each site, storing them in a variable called mData. My challenge now is to return and utilize this variable as JSON input to construct a tree map once the entire recursion process is completed. Each async call either returns an array of sites or a single site.

How can I ensure that mData is returned only after the full recursion is finished? What indicators can be used to determine when the recursion has concluded so that a call can be made to the desired function?

Answer №1

To implement a recursive function in AngularJS using promises and the $q service, you can structure your code as shown below. This assumes that the foo.getStuff(url) function returns an Angular promise.

function fetchRecursiveData(url) {
    return foo.getStuff(url).then(function(data){
        var result = {} // initialize the result object
        var promises = [] // array to store promises for recursive calls
        
        for (x in data) {
            promises.push(fetchRecursiveData(url).then(function(r){
                // update result with fetched data 'r'
            }))
        }
        
        // Wait for all recursive calls to complete before resolving the main promise with the final result
        return $q.all(promises).then(function(){return result}) 
    })
}

fetchRecursiveData(ROOT_URL).then(callback)

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

The returned type of intersected functions in Typescript does not match the inferred type

While attempting to extract the return type of an intersected request, I encountered a discrepancy between the return type and the inferred type. Check out the shortened URL for more details: https://tsplay.dev/mAxZZN export {} type Foo = (() => Promis ...

Disable event listener when the controls are unlocked using the pointerlock controls in three.js

While navigating a model with threejs pointerlock controls, clicking on specific sections of the model directs users to different parts of the site. However, an issue arises when the camera is centered over a section and the user exits the pointerlock. Upo ...

Can VueJS support multiple v-slots in a component?

I recently set up vee-validate v3.0 for validation in my project and everything was going smoothly until I tried to style my elements. Despite following the documentation on styling and making changes to the vee-validate config, I encountered a new issue - ...

The value of request.url in NodeJS is consistently set to "/"

As a beginner in learning NodeJS, I am curious about how to determine the URL of a request in order to execute different functions. However, every time I use request.url, it seems to only return "/". My approach involves using NodeJS without additional m ...

Using AngularJS to manage cookies along with arrays

I am passing my data in this way $cookies.putObject("currentLocation,values,allLocList", obj, vm.tempData, vm.allLocationList); The objects obj and vm.tempData are being sent as objects, while vm.allLocationList is an array that contains a JSON object. W ...

I have a few inquiries about my nodejs studies. Can you assist me, please?

As I delve into my studies of nodejs, some burning questions have arisen. Is it true that nodejs supports all JavaScript? In the official documentation, it mentions using the latest v8 engine. However, I have reservations about whether all JavaScript ...

What steps can be taken to diagnose the cause of a failed Jquery AJAX request?

I am attempting to utilize the Yahoo Finance API to retrieve data in CSV format through Javascript. However, my current implementation shown below is not successful. $.ajax({ type: "GET", url: "http://finance.yahoo.com/d/quotes.csv?s=RHT+MSFT&f=sb2b3j ...

Utilizing a loop for setting variable values in JavaScript

Using both JavaScript and JQuery. Let's imagine there is an array called ListArray with various sentences inside. Sounds easy enough. Is there a way to achieve this? var List = for (var i = 0; i < 10; i++) { //iterate over an array here to c ...

Exploring the Modularity of Post Requests with Node.js, Express 4.0, and Mongoose

Currently, I am immersed in a project that involves utilizing the mean stack. As part of the setup process for the client-side, I am rigorously testing my routes using Postman. My objective is to execute a post request to retrieve a specific user and anot ...

Unable to assign a value to a variable in JavaScript

Today, I delved into the world of JavaScript and decided to test my skills by creating a page that changes images when clicking on a div. Everything worked perfectly until I wanted to add an input element to specify how many steps to jump each time the but ...

Error: The property 'parentNode' cannot be read because it is null

I wanted to test if my laptop can handle WebGL by loading examples from my instructor's webpage. The examples on the webpage worked fine, just showing a square within a square. I then decided to copy the exact codes into a notepad text editor, saved t ...

Injecting variable styles into my VueJS component

I am currently working on developing a custom progress bar to visualize the percentage of completed tasks. The approach I am taking involves using v-bind:styles and passing {width: dynamicWidth + '%'} to regulate the progression of the bar. To ac ...

Experience the power of live, real-time data-binding for date-time input with AngularFire in 3 different

Here is a simplified version of my code snippet: tr(ng-repeat='entry in ds3.entries | orderBy:orderByField:reverseSort | filter:query as results') td input.screen(type='datetime-local', ng-model='entry.date_recei ...

Step by step guide on integrating ReactJS into your current node.js backend application

I am currently working on a basic node.js API Setup: | project-name | public | index.html | ... some static js/css | app.js | package.json app.js var express = require('express'), bodyParser = require('body-parser'), ...

How can I transfer a JavaScript value to PHP for storage in an SQL database?

<script> var latitudeVal = document.getElementById("latitude"); var longitudeVal = document.getElementById("longitude"); function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition); ...

When I try to run Parcel, my ReactJS website just won't deploy in a serverless environment

For a while now, I've been working on a website using serverless. Everything was going smoothly until this morning when I encountered an issue with pushing updates from my site to the serverless platform. When trying to push, I received the following ...

Exploring the power of regular expressions in Javascript when used between

Consider the scenario outlined in the text below I desire [this]. I also desire [this]. I do not desire \[this] I am interested in extracting the content enclosed within [], but not including \[]. How should I approach this? Currently, I have ...

Encountering issues with Office.context.document.getFileAsync function

I am experiencing a strange issue where, on the third attempt to extract a word document as a compressed file for processing in my MS Word Task Pane MVC app, it crashes. Here is the snippet of code: Office.context.document.getFileAsync(Office.FileType.Co ...

Presenting a trio of distinct tables each accompanied by its own unique button option

I am attempting to create a functionality where there are 3 buttons and when a user clicks on one of them, it shows the corresponding table while hiding the other two. I have experimented with using getElementById to manipulate the display property of the ...

Difficulty arising from commands

I am currently familiarizing myself with the use of directives in AngularJS. I have a password.html file that contains an input field for passwords, and I have created a custom directive called 'passwordRequirement' to enforce specific requiremen ...