NgUpgrade: Unable to use templateUrl when upgrading Angular1 components
I found a quite cheap solution for the issue.
Just use template: require('./remote-url.component.html')
instead of templateUrl: './remote-url.component.html'
and it should work just fine!
After trying require with requireJS and the text plugin which did not work for me, I managed to make it work using 'ng-include' as follow:
angular.module('appName').component('nameComponent', {
template: `<ng-include src="'path_to_file/file-name.html'"></ng-include>`,
I hope this helps!
This is really frustating because the Angular upgrade documentation specifically says it's ok to use templateUrl. Never mentions this async issue. I've found a way around it by using the $templateCache. I didn't want to change my angular 1 directive because it is used my angular 1 apps and will also be used by angular 4 apps. So I had to find a way to modify it on the fly. I used $delegate, $provider, and $templateCache. My code is below. I also use this to remove the replace attribute since it is deprecated.
function upgradeDirective(moduleName, invokedName) {
/** get the invoked directive */
angular.module(moduleName).config(config);
config.$inject = ['$provide'];
decorator.$inject = ['$delegate', '$templateCache'];
function config($provide) {
$provide.decorator(invokedName + 'Directive', decorator);
}
function decorator($delegate, $templateCache) {
/** get the directive reference */
var directive = $delegate[0];
/** remove deprecated attributes */
if (directive.hasOwnProperty('replace')){
delete directive.replace;
}
/** check for templateUrl and get template from cache */
if (directive.hasOwnProperty('templateUrl')){
/** get the template key */
var key = directive.templateUrl.substring(directive.templateUrl.indexOf('app/'));
/** remove templateUrl */
delete directive.templateUrl;
/** add template and get from cache */
directive.template = $templateCache.get(key);
}
/** return the delegate */
return $delegate;
}
}
upgradeDirective('moduleName', 'moduleDirectiveName');
Most of the answers given here involve pre-loading the template in some way so as to make it available synchronously to the directive.
If you want to avoid doing this - e.g. if you have a large AngularJS application that contains many templates, and you don't want to download them all up front - you can simply wrap your directive in a synchronously loaded version instead.
E.g., if you have a directive called myDirective
, which has an asynchronously loaded templateUrl
which you don't want to download up front, you can do this instead:
angular
.module('my-module')
.directive('myDirectiveWrapper', function() {
return {
restrict: 'E',
template: "<my-directive></my-directive>",
}
});
Then your Upgraded Angular directive just needs to supply 'myDirectiveWrapper'
instead of 'myDirective'
in it's super()
call to the extended UpgradeComponent
.