TransWikia.com

es5 using promise but returns defered before resolving

Stack Overflow Asked by Rodney Wormsbecher on November 4, 2021

I am having a recursive function which works well and get all the results that I need. once it get’s into the second "then" block it logs all the results. However the "return deferred.promise" happens before the data has been loaded, which kind of confuse me as the promise will only be resolved after the data has been loaded. If I move the return deferred.promise up in the 2nd then block, the consuming code tell me this method is not thennable. kKind of confused which part I am missing, any help will be much appreciated.

The code

 function getUserGroups(groups, nextLink) {
            var deferred = $q.defer();
            var intermediaryGroupResult = groups;
            var endpoint = '';
            if (nextLink != '' && nextLink !== undefined) {
                endpoint = nextLink;
            } else {
                endpoint = config.baseGraphApiUrl + "me/memberOf?$select=id,displayName,securityEnabled";
            }
      

            (function (intermediaryGroupResult) {
                $http.get(endpoint).then(function (result) {

                    var dataNextLink = result.data['@odata.nextLink'];
                    var resultsFromGraph = result.data.value;

                    for (var i = 0; i < resultsFromGraph.length; i++) {
                        intermediaryGroupResult.push(resultsFromGraph[i]);
                    }

                    if (dataNextLink != '' && dataNextLink !== undefined) {
                        getUserGroups(intermediaryGroupResult, dataNextLink)
                    } else {
                        console.log('groups', intermediaryGroupResult);
                        return intermediaryGroupResult;
                    }
                }).then(function (allGroups) {
                    console.log('all groups', allGroups)

                    deferred.resolve(allGroups);
               
                });
            })(intermediaryGroupResult);

         
            return deferred.promise;
        }

The console:
enter image description here

2 Answers

A few pointers:

  • the Deferrerd is unnecessary. $http.get().then() returns a Promise, which can itself be returned by the function.
  • the IIFE is unnecessary. Presumably, you are trying to ensure that the original groups passed to the function is not mutated.
  • to create a copy of groups with additional members from result.data.value use Array.prototype.concat() and spread syntax as follows; [].concat(...groups, ...result.data.value).
  • the recursive call to getUserGroups() is missing a return.

With a couple of further simplifications, the function can be written as follows:

function getUserGroups(groups, nextLink) {
    return $http.get(nextLink || config.baseGraphApiUrl + "me/memberOf?$select=id,displayName,securityEnabled")
    .then(function(result) {
        var intermediaryGroupResult = [].concat(...groups, ...result.data.value);
        var dataNextLink = result.data['@odata.nextLink'];
        return dataNextLink ? getUserGroups(intermediaryGroupResult, dataNextLink) : intermediaryGroupResult;
    });
}

Answered by Roamer-1888 on November 4, 2021

In javascript, there is very little blocking code. What that means is that the http request will run in the background, but your code will still continue execute. What's happening is that you're returning an unresolved promise before the data loads, but it'll resolve when the data loads. This is fine, you just have to use .then on the result of the function call.

Answered by Aplet123 on November 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP