Reputation: 1390
I found this thread How to handle multiple JS libraries with different loading times in Angular? which I am using to add d3.js to my header. I now have to add d3.legend.js aswell. How would I accomplish this in a callback-manner?
var d3js = angular.module('d3', []);
d3js.factory('d3Service', ['$document', '$q', '$rootScope', '$window',
function($document, $q, $rootScope, $window) {
var d = $q.defer();
function onScriptLoad() {
// Load client in the browser
$rootScope.$apply(function() { d.resolve($window.d3); });
}
// Create a script tag with d3 as the source
// and call our onScriptLoad callback when it
// has been loaded
var scriptTag = $document[0].createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.async = true;
scriptTag.src = 'lib/d3.v3.js';
scriptTag.onreadystatechange = function () {
if (this.readyState == 'complete') onScriptLoad();
}
scriptTag.onload = onScriptLoad;
var s = $document[0].getElementsByTagName('body')[0];
s.appendChild(scriptTag);
//this is now where I have to add d3.legend.js which depends on the successful loading of d3.js.
return {
d3: function() { return d.promise; }
};
}]);
Upvotes: 0
Views: 92
Reputation: 4378
A cut-down version of the original idea:
var app = angular.module('SomeApp', []);
app.factory('LibraryFactory', function () {
var factory = {};
factory.getD3 = function(callback) {
if(!window.d3) {
var script = document.createElement("script");
script.src = "https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.9/d3.min.js";
document.head.appendChild(script);
script.onload = function() {
callback(window.d3);
};
} else {
callback(window.d3);
}
};
factory.getD3Legend = function(callback) {
if(!window.d3.legend) {
//...ditto
}
};
return factory;
});
And to use the factory (eg, in a controller) you can chain the calls:
app.controller('SomeTrialCtrl', function ($scope, LibraryFactory) {
LibraryFactory.getD3(function (d3) {
LibraryFactory.getD3Legend(function (d3WithLegend) {
// place code using the libraries here
});
});
});
Or in the case of d3.legend, the factory.getD3Legend function could call the getD3 function internally to keep things simpler. Like:
factory.getD3Legend = function(callback) {
factory.getD3(function(d3) {
if(!d3.legend) {
//...ditto
}
callback(d3);
}
};
That's the basic idea anyway. @aarosil's answer in the original post probably is more Angular-correct.
Upvotes: 1
Reputation: 848
I just loop through the array of libraries that I need to add and add them one by one see code below:
var _libraries: [
'scripts/d3.min.js',
'scripts/moment.min.js'
]
for (var i = 0, len = _libraries.length; i < len; i++) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = _libraries[i];
document.body.appendChild(s);
}
Hope this helps.
Upvotes: 0