Loading Angular templates from an iframe proxy

Recently, I had to develop a custom SharePoint 2013 Metadata Navigation component that with the same look and feel as OOB component. I choose to develop a SharePoint 2013 Provider hosted add-in and enable my component by programmatically adding a Script Editor webpart into the list views. I used Angular 1.5 for the UI and interaction.

With the Metadata Navigation Component, I had to quickly show the complete tree of Metadata Navigation (along with their count) from database. I hated to query the template, load the data via Ajax and then ask Angular to compile the template into the view.

I thought it is better to pre-render the data with the template on server, so that the time for component to render on the browser is reduced. Plus, the HTML output can be cached by using MVC OutputCache attribute and be reused for multiple users. Also, all this communication took place over an iframe proxy so that the user remains authenticated on the provider hosted add-in.

Whenever, we ask Angular to load a template, $templateRequest service is invoked. It makes an HTTP call and puts the template into the $templateCache before forwarding to the required component. Generally, we can only specify the http headers that are being used by the $templateRequestProvider.

Now came the challenge as I needed to request the template to a proxy iframe using postmessage. The proxy page then requests the backend for the template. I needed to provide my own template loading functionality.

To do this, we need to use the Angular decorator pattern which allows us to modify or replace the behaviour of the existing Angular Services

module.config(["$provide", function ($provide) {
$provide.decorator("$templateRequest", [
"$delegate", "$q", "$templateCache",// DI specifications
function ($delegate, $q,$templateCache) {
// replace the delegate function
$delegate = function (tpl) {
var defer = $q.defer();
// convert the tpl from trustedvaluetoken to string
if (typeof (tpl) !== "string" || !!$templateCache.get(tpl)) {
tpl = $sce.getTrustedResourceUrl(tpl);
}
// make proxy call and resolve the promise;
return defer.promise;
}
// return the modified delegate function
return $delegate;
}]);
}]);

As you can see in the gist, I have replaced the $templateRequest function with my own. In the function I will make a call to postMessage, receive the data and load into the $templateCache before resolving the promise that I have returned.

Have a better way to solve this problem? Please share your thoughts.