Chris Prior Chris Prior - 1 year ago 63
AngularJS Question

How to render an AngularJS template to a String without causing InProg error?

I am trying to write a service which renders a given template and scope to a string.

This is the code:

utilModule.factory('CompilerService', ['$compile', '$templateCache',
function ($compile, $templateCache) {
return {
renderTemplateToString: function(templateName, scope) {
var template = $templateCache.get(templateName);
var linkFn = $compile(template);
var linkedContent = linkFn(scope);
scope.$apply();

return linkedContent.html();
}
}
}]);


When I call this however, I am getting the angular InProg err, caused by the call to $apply():

https://docs.angularjs.org/error/$rootScope/inprog

I am calling $apply() in order for the variables to be substituted within the template before retrieving the html.

Any ideas on how to achieve this without the InProg error?

Answer Source

You have two options:

if ( !scope.$$phase )
    scope.$apply();

this is checking if the code is being executed during a $digest cycle.

However, $timeout is preferred:

$timeout( function(){
  var template = $templateCache.get(templateName);
                var linkFn = $compile(template);
                var linkedContent = linkFn(scope);
}, 0)

EDIT: in order to use premises, you should do something like that:

    renderTemplateToString: function(templateName, scope) {
            var deferred = $q.defer();
            $timeout(function(){
               var template = $templateCache.get(templateName);
               var linkFn = $compile(template);
               var linkedContent = linkFn(scope);
               scope.$apply();
               deferred.resolve( linkedContent.html() );
            }, 0);

            return deferred.promise;
    }

$timeout is waiting to the $digest to finish before executing