Angular directive templateUrl relative to .js file

angularjs, javascript, path

Solution

The currently executing script file will always be the last one in the scripts array, so you can easily find its path:

// directive.js

var scripts = document.getElementsByTagName("script")
var currentScriptPath = scripts[scripts.length-1].src;

angular.module('app', [])
    .directive('test', function () {
        return {
            templateUrl: currentScriptPath.replace('directive.js', 'directive.html')
        };
    });

If you're not sure what is the script name (for example if you're packing multiple scripts into one), use this:

return {
    templateUrl: currentScriptPath.substring(0, currentScriptPath.lastIndexOf('/') + 1) 
        + 'directive.html'
};

Note: In cases where a closure is used, your code should be outside to ensure that the currentScript is evaluated at the correct time, such as:

// directive.js

(function(currentScriptPath){
    angular.module('app', [])
        .directive('test', function () {
            return {
                templateUrl: currentScriptPath.replace('directive.js', 'directive.html')
        };
    });
})(
    (function () {
        var scripts = document.getElementsByTagName("script");
        var currentScriptPath = scripts[scripts.length - 1].src;
        return currentScriptPath;
    })()
);

Problem

I'm building an angular directive which will be used in a few different locations. I can't always guarantee the file structure of the app the directive is used in, but I can force the user to put the `directive.js` and `directive.html` (not the real file names) in the same folder. When the page evaluates the `directive.js`, it considers the `templateUrl` to be relative to itself. Is it possible to set the `templateUrl` to be relative to the `directive.js` file? Or is it recommended to just include the template in the directive itself. I'm thinking I may want to load different templates based on different circumstances, so would prefer to be able to use a relative path rather than updating the `directive.js`

Original source

Related problems