0

I want to set different styles for my app, depending on a URL parameter (that I already got).

I tought to do something like this:

let dynamicCSS;

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: [require('./app.component.css'), require('./app.component.' + dynamicCSS + '.css')],
    encapsulation: ViewEncapsulation.None
})
export class App.........

But in this case, the "require" says: "Cannot be found", and I don't know how to access my dynamicCSS variable from my ngOnInit().

How can I solve this?

happy songs
  • 835
  • 8
  • 21
Liu
  • 66
  • 1
  • 7
  • Please add context, the provided info is not enough. You are targeting the app and your style change is in the component. – onrails Jun 07 '22 at 20:00

2 Answers2

1

You do not have to include the require(). This should do the trick

styleUrls: ['./app.component.css', './app.component.' + dynamicCSS + '.css']

Or to make it even cleaner:

styleUrls: ['./app.component.css', `./app.component.${dynamicCSS }.css`]

Make sure to add the dynamicCSS as a variable in the component file, but outside the component itself like in the example below (not a real world exaple since these 2 urls return the same file)

enter image description here

Wolfyr
  • 409
  • 3
  • 11
  • Ok, got it. And how do I change the used CSS? For example: I will receive via URL, the style I need to use. So, after identify it on my ngOnInit, how do I apply it to html? And more, how do I define a default style? Is it possible? – Liu Jun 07 '22 at 20:16
  • 1
    You probably can't in the ngOnInit, because you cannot use variables from inside the component class in the styleUrls array. I think your best bet is to create a resolver that sets some variable in a (static) class that you can use outside your component class. Not really sure if the resolver will hook before or after the url is changed wth your parm, otherwise you could abuse a route guard or create your own route interceptor that catches every route change to set the variable there. – Wolfyr Jun 07 '22 at 20:23
  • 1
    default styling could be done with a stylesheet called: app.component.default.scss for example, where default is just the default value of the variable you use in the stylesheet path. If there is no parm in the URL to overwrite the default, the resolver just sets the variable to "default" or doens't change it if it already has that value – Wolfyr Jun 07 '22 at 20:26
  • 1
    Maybe you can also just subscribe to the router events in the component (or in a parent component) or read the parm from the url in the ngOnInit and then set the variable from the component in the service or class you use for the stylesheet variables. But if you do this in the component itself I don't think it will work, you probably have to set the variable before the component inits – Wolfyr Jun 07 '22 at 20:33
0

I went back to work on this and figured out how to do what I needed. It was simpler than I imagined. All I had to do was create a function like this:

loadCSS() {
    let fileRef;
    fileRef = document.createElement('link');
    fileRef.setAttribute('rel', 'stylesheet');
    fileRef.setAttribute('type', 'text/css');
    fileRef.setAttribute('href', '../../assets/dynamicStyles/appointment2.component.css');
    if (typeof fileRef !== 'undefined') {
        document.getElementsByTagName('head')[0].appendChild(fileRef);
    }
}

This function injects a new CSS Style into the page, that way I can replace the entire style on the page.

NOTE 1 The file MUST be inside /assets.

NOTE 2 The file MUST be .css, cannot be .scss.

NOTE 3 No need to add the file path in "styles" inside angular.json, nor in @Component inside my app.component.ts.

Liu
  • 66
  • 1
  • 7