Chris Prior Chris Prior - 3 months ago 27
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

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