0

I am using AngularJS, I have a function in a service with nested promises:

this.getOfferStatus = function (offer) {

    if(offer.isDraft){
        return 'Draft';
    } else {
        this.isProcessed(offer).then(function (isProcessed) {
            if (isProcessed) {
                this.isAccepted(offer).then(function (isAccepted) {
                    if (isAccepted) {
                        if (isExpired(offer)) {
                            return 'Expired';
                        } else {
                            if (this.isActive(offer).then(function (isActive) {
                                    return 'Active';
                                }, function (err) {
                                    console.error(err);
                                }));
                            }
                        } else {
                            return 'Rejected';
                        }
                    }, function (err) {
                        console.error(err);
                    })
                } else {
                    return 'Pending';
                }
            }, function (err) {
                console.error(err);
            });
        }
    }
}

But, when I call this function in my controller, I get this error:

XHR finished loading: GET "http://localhost:8080/localbusiness/1/offers/Absolute". Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [] http://errors.angularjs.org/1.5.0/$rootScope/infdig?p0=10&p1=%5B%5D at angular.js:68 at Scope.$digest (angular.js:16702) at Scope.$apply (angular.js:16928) at done (angular.js:11266) at completeRequest (angular.js:11464) at XMLHttpRequest.requestLoaded (angular.js:11405) Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: []


isProcessed() function:

this.isProcessed = function (offer) { 
    var deferred = $q.defer();
    var LocalBusinessResource =
        $resource(apiService + '/offers/:id/processed', {id: '@id'});
    LocalBusinessResource.get({id: offer.id}, function (result) {
        deferred.resolve(result); 
    }, function (err) { 
        return $q.reject(err);
        alert('check your server connection ' + angular.toJson(err)); 
    });
    return deferred.promise; 
}

In my controller:

$scope.getStatus = function(offer){ 
    return offerService.getOfferStatus(offer);
}; 
9
  • Don't return anything before function end. return after all your function executed. Commented Apr 1, 2016 at 12:52
  • You're also trying to return bare strings instead of resolved promises; that isn't going to work either. Commented Apr 1, 2016 at 12:53
  • @ArunShinde do you have any fixes? Commented Apr 1, 2016 at 13:08
  • What does isProcessed() do? I suspect that is creating an infinite recursive loop. Also using the this keyword inside a fulfillment handler of a .then method won't work. The promise spec says that the this keyword should be undefined in strict mode and the global context in sloppy mode. Commented Apr 1, 2016 at 13:09
  • @georgeawg here is isProcessed() function: this.isProcessed = function (offer) { var deferred = $q.defer(); var LocalBusinessResource = $resource(apiService + '/offers/:id/processed', {id: '@id'}); LocalBusinessResource.get({id: offer.id}, function (result) { deferred.resolve(result); }, function (err) { return $q.reject(err); alert('check your server connection ' + angular.toJson(err)); }); return deferred.promise; } Commented Apr 1, 2016 at 13:26

2 Answers 2

0

Check this might solve your problem.

this.getOfferStatus = function (offer) {
   var parent = this;
    if(offer.isDraft){
        parent.setStatus('Draft')
    }else{
        this.isProcessed(offer).then(function (isProcessed) {
            if (isProcessed) {
                this.isAccepted(offer).then(function (isAccepted) {
                    if (isAccepted) {
                        if (isExpired(offer)) {
                            parent.setStatus('Expired')
                        } else {
                            if (this.isActive(offer).then(function (isActive) {
                                    parent.setStatus('Active')
                                }, function (err) {
                                    console.error(err);
                                }));
                        }
                    }else{
                        parent.setStatus('Rejected')
                    }
                }, function (err) {
                    console.error(err);
                }) 
            } else {
                parent.setStatus('Pending')
            }
        }, function (err) {
            console.error(err);
        });
    }

}

this.setStatus = function(status){
    $scope.status = status;
}
Sign up to request clarification or add additional context in comments.

Comments

0

@georgeawg I expect getOfferStatus to return a string

The function only returns a string when offer.isDraft is truthy otherwise it returns null.

this.getOfferStatus = function (offer) {

    if(offer.isDraft){
        //Returns a string here
        return 'Draft';
    }else{
        this.isProcessed(offer).then(function anon1(isProcessed) {
            if (isProcessed) {
                this.isAccepted(offer).then(function anon2(isAccepted) {
                    if (isAccepted) {
                        if (isExpired(offer)) {
                            //This returns to function anon2
                            return 'Expired';
                        } else {
                            if (this.isActive(offer).then(function anon3(isActive) {
                                    //This returns to anon3
                                    return 'Active';
                                }));
                        }
                    }else{
                        //This returns to anon2
                        return 'Rejected';
                    }
                })
            } else {
                //This returns to anon1
                return 'Pending';
            }
        }, function (err) {
            console.error(err);
        });
    }
//
//Returns null here
//
}

There is only one return statement that returns to getOfferStatus. All the other return statements are inside anonymous functions inside .then methods.

It is erroneous to think those return statements will return a string to a parent (or grandparent) function. Returns need to be done for every level of nesting.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.