I am trying to dynamically add css to my html head using angular js. Here is sample code
You should use ng-href instead of href.
<link ng-repeat="stylesheet in stylesheets" ng-href="{{stylesheet.href}}" type="{{stylesheet.type}}" rel="stylesheet" />
Example
I made a AngularJS service to use easily the @Artem solution.
It's here on GitHub.
For anyone wishing to create truly dynamic CSS at runtime with AngularJS this is what I used.
index.html
<head>
<style type="text/css" ng-bind-html="styles"></style>
</head>
cssService
this.$rootScope.myStyles = ".test { color : red; }";
This is just an example, it may be better for you to put the styles into an indexController if you have one and keep it off the $rootScope
I've created a very simple example of how make a conditionaly css addition
<link rel="stylesheet" ng-if="lang_direction == 'rtl'" ng-href="{{lang_direction == 'rtl' ? 'css/rtl.css' : ''}}" >
There's a another option using $route.resolve and promises. This will wait until the CSS is actually loaded not only added to the head (after that the browser just starts retrieving the file and depending on CSS size can cause page reflow).
// Routing setup
.config(function ($routeProvider) {
$routeProvider
.when('/home', {
controller: 'homeCtrl',
templateUrl: 'home.tpl.html'
}).when('/users', {
controller: 'usersCtrl',
controllerAs: 'vm',
templateUrl: 'users.tpl.html',
resolve: {
load: ['injectCSS', function (injectCSS) {
return injectCSS.set("users", "users.css");
}]
}
}).otherwise({
// default page
redirectTo: '/home'
});
})
Service implementation
.factory("injectCSS", ['$q', '$http', 'MeasurementsService', function($q, $http, MeasurementsService){
var injectCSS = {};
var createLink = function(id, url) {
var link = document.createElement('link');
link.id = id;
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
return link;
}
var checkLoaded = function (url, deferred, tries) {
for (var i in document.styleSheets) {
var href = document.styleSheets[i].href || "";
if (href.split("/").slice(-1).join() === url) {
deferred.resolve();
return;
}
}
tries++;
setTimeout(function(){checkLoaded(url, deferred, tries);}, 50);
};
injectCSS.set = function(id, url){
var tries = 0,
deferred = $q.defer(),
link;
if(!angular.element('link#' + id).length) {
link = createLink(id, url);
link.onload = deferred.resolve;
angular.element('head').append(link);
}
checkLoaded(url, deferred, tries);
return deferred.promise;
};
return injectCSS;
}])
You could add a timeout using tries if this is something you would like to include.
Check out this post for more details:https://medium.com/angularjs-meetup-south-london/angular-dynamically-injecting-css-file-using-route-resolve-and-promises-7bfcb8ccd05b