0

I have a controller calling a service, which performs a number of http calls and returns back a set of data to my controller. The problem i am facing is that my service returns some data (typically emtpy) before all the http calls have been completed, and as a result, $scope.myForksLinks is undefined.

Controller:

myService.getMyData()
    .then(function(response) {

        $scope.myUrl = response.myForksLinks;

    });

MyService:

handleResolveReject() {
    return promise.then(function(v) {
        return {v:v, status: "resolved"};
    }, function(e) {
        return {e:e, status: "rejected"};
    });
},

getMyData() {

    const that = this;
    var deferred = that._$q.defer();
    var httpResponse = [];

    var httpLinks = [
        {myTablesLinks: this.tablesLinks}, // this.tablesLinks = [http://tablelink1.come, http://anotherTableLink.com]
        {myGlassesLinks: this.glassesLinks},
        {myPlatesLinks: this.platesLinks},
        {myCupsLinks: this.cupsLinks},
        {myForksLinks: this.forksLinks},
    ]

    var getData = function() {
        _.forEach(httpLinks, function(httpSet, k) {
            _.forEach(httpSet, function(links, httpName) {
                var promises = [];

                angular.forEach(links, function(link) {
                    var promise = that._$http({
                        method: 'GET',
                        url: link + '/my/end/point',
                        responseType: 'json'
                    });
                    promises.push(promise)
                });

                return Promise.all(promises.map(that.handleResolveReject))
                    .then(function(results)) {

                        httpResponse.push({httpName: results.filter(x => x.status === 'resolved')});

                    });
            });
        });

        return httpResponse;
    };

    deferred.resolve(getData());
    return deferred.promise;


}
Oam Psy
  • 8,555
  • 32
  • 93
  • 157
  • Maybe it's a `Promise.all` of `Promise.all`s? – Faizuddin Mohammed Jan 29 '18 at 07:47
  • `function(e) { return {v:v, status: "rejected"}; }` this function throws. So `handleResolveReject` doesn't handle promise rejection. – Yury Tarabanko Jan 29 '18 at 07:49
  • @YuryTarabanko - it shouldnt, as its using the Reflect pattern here: https://stackoverflow.com/questions/31424561/wait-until-all-es6-promises-complete-even-rejected-promises – Oam Psy Jan 29 '18 at 07:53
  • @OamPsy I'm not sure what the heck is "Reflect pattern". But your function when called throws ReferenceError because `v` is not defined. So the promise you return from `handleResolveReject` still rejects making entire `Promise.all` result to reject fast. – Yury Tarabanko Jan 29 '18 at 07:58
  • @YuryTarabanko updated code, there was a typo copying. Added link to Reflecf in previous response. – Oam Psy Jan 29 '18 at 08:03

1 Answers1

0

Something along these lines:

var allPromises = [];
_.forEach(httpLinks, function (httpSet, k) {
    allPromises = _.map(httpSet, function (links, httpName) {
        var promises = [];
        angular.forEach(links, function (link) {
            var promise = that._$http({
                method: 'GET',
                url: link + '/my/end/point',
                responseType: 'json'
            });
            promises.push(promise);
        });

        return Promise.all(promises.map(that.handleResolveReject))
            .then(function (results) {
                httpResponse.push({ httpName: results.filter(x => x.status === 'resolved') });
            });
    });
});
Promise.all(allPromises).then(() => {
    // here you go
})
Faizuddin Mohammed
  • 4,118
  • 5
  • 27
  • 51