I am trying to get a dynamic style-sheet change for a singlepage-application to work in Angular. The idea is to create different themes and let the users choose from them in a dedicated menu. There may be many themes, so nevermind that the example below only has two variants. The functionality is ready. As of now, I have collected all styles in single large scss-files, one for each theme. (Note that I am well aware that in Angular you often split the styles in many sub-scss files, for each component. But for this idea to work, I wanted to have it all in single files for each theme). I have the menu working, and use localstorage for the app to remember which theme has been chosen, since the site has to be reloaded for the changes to take effect.
Now for the problem: In app.component.ts, the style sheet is defined, in standard form (i.e. styleUrls: [filename]). When using a static file path/name there, and when using a variable, defined just outside the @component-code, the styles works perfectly. But for the dynamic theme change, I have a simple fetch of the variable from localstorage:
var settingsString = localStorage.getItem('usergraphicsdata');
if (isDefined(settingsString)) {
let myUserSettings = JSON.parse(settingsString);
const themename = myUserSettings.theme;
It all works there too. Different console.logs confirms it understands everything it should. But then comes the problem.
if(themename == "theme1"){
var stylePath = "./app.component_theme1.scss";
var graphicFolder = '/assets/theme1/';
} else if(themename == "theme2"){
var stylePath = "./app.component_theme2.scss";
var graphicFolder = '/assets/theme2/';
}
}
Then comes the @component with its styleUrls: [stylePath]
For some reason the if-conditions are not regarded, and the result is always that the theme declared first (in the above case "theme1") will be active. So if I just change the order in the condition, and put the code for theme 2 first, that will be chosen for the site, disregarding which theme variable is actually fetched from localstorage
I have tried several other variants as well, but this one seems to be closest to a solution. Could it be an issue with Angular limiting style changes in runtime contra build? Or have I forgotten something basic in the if-condition?
Best regards and sorry for my limited english. Per
why don't you solve it with routing? Duplicate the component for each theme, just with a different css-file but use for all those components the same html-file and put in the menu a link to that component (with a specific theme). The added value would be that the theme name also appears in the url and you can easily apply different logic without things getting to be convoluted (different typescript-files).
Something like this:
@Component({
selector: 'sunflower',
templateUrl: './detail.component.html',
styleUrls: ['./sunflower.component.scss']
})
export class SunflowerComponent {
@Component({
selector: 'roses',
templateUrl: './detail.component.html',
styleUrls: ['./roses.component.scss']
})
export class RosesComponent {
If you tried it, please share the problems you've encountered.
update
I made an extremely basic demo (that I've tested), you can find it here:
Take care & good luck.