Dynamically Injecting Script Tags With AngularJS

Tuesday, April 8, 2014

A few months ago I found myself in a situation where I had to throw some dynamically generated scripts into the browser for testing (and occasionally inspecting and debugging). I wrote a small custom directive to take care of most of the work.

<div ng-controller="mainController">   

    <div otc-scripts scripts="scripts">

    </div>

</div>

In the above markup, it’s the mainController that will fetch the script text for execution, which I’ll simulate with the code below.

app.controller("mainController", function($scope, $timeout) {
    $scope.scripts = [];

    $timeout(function () {
        $scope.scripts = [
            "alert('Hello');",
            "alert('World');"
        ];
    }, 2000);
});       

The rest of the work relies on the otcScripts directive, which watches for a new script array to appear and then creates script tags and places the tags into the DOM.

app.directive("otcScripts", function() {

    var updateScripts = function (element) {
        return function (scripts) {
            element.empty();
            angular.forEach(scripts, function (source, key) {
                var scriptTag = angular.element(
                    document.createElement("script"));
                source = "//@ sourceURL=" + key + "\n" + source;
                scriptTag.text(source)
                element.append(scriptTag);
            });
        };
    };

    return {
        restrict: "EA",
        scope: {
          scripts: "="  
        },
        link: function(scope,element) {
            scope.$watch("scripts", updateScripts(element));
        }
    };
});

I’m sure there are many different approaches to achieving the same result, but note the above code uses document.createElement directly, as this appears to be one foolproof approach that consistently works. The directive also prepends a @sourceURL to the script. If you give your @sourceURL a recognizable name, you’ll be able to recognize the code bits a little easier in the Chrome debugger.


Comments
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!