0

I'm facing an infinite loop when trying to make AngularJS display a promise, as explained in this article: http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/.

I first call $parseProvider.unwrapPromises(true);:

.config(["$parseProvider",
function($parseProvider) {
    $parseProvider.unwrapPromises(true);
}])

Here is the factory I use to access a message:

app.factory("MessageHelper", [
function() {

    // omitted for brevity:
    // calling the server for getting the messages

    return {

        get: function(code) {
            var args = Array.prototype.slice.call(arguments);
            args.shift();
            if (messages) {
                return $q.when(format(messages[code], args));
            }
            var deferred = $q.defer();
            deferredMessages.push({ code: code, args: args, deferred: deferred });
            return deferred.promise;
        }

    };

}]);

Then, in a controller:

$scope.msg = {
    get: function() {
        return MessageHelper.get.apply(this, arguments);
    }
};

Finally, in a view:

<span>{{msg.get("existing.message.code", "first param", "second param")}}</span>

And here is the infinite loop: $scope.msg.get gets called infinitely... Any idea why?

1 Answer 1

1

You can't have anything with a side effect to scope in any angular expressions, otherwise the infinite loop will occurred.

It's by design to rerun all the expressions repeatedly until nothing has changed. So at the time the promise is resolved, the expressions will get evaluated again.

To avoid that, you could move the msg.get call into the controller and store the promise as an another property in $scope:

$scope.msg = {
    get: function() {
        return MessageHelper.get.apply(this, arguments);
    }
};

$scope.resultMsg = $scope.msg.get("existing.message.code", "first param", "second param");

and use that in the template instead:

{{resultMsg}}

Hope this helps.

Sign up to request clarification or add additional context in comments.

5 Comments

Which side effect to scope does my code generate? So you think there is no possibility to pass the message code and parameters from the view directly?
When any request made by $http is finished, the $rootScope.$apply() will be called automatically, see this code. That will trigger all expressions to be re-evaluated. I would say it is an indirect side effect :)
Oh, look at your code again, there might not be any $http call, but something else may trigger the $digest loop instead.
Ok, found it, a deferred.resolved() also trigger a $rootScope.$digest() as well.
Thank you for your investigation. I'll try to find another way then. Nice mastery of AngularJS BTW ;)

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.