7

Using plain old javascript, this is so simple:

myElement.style.setProperty('property', 'value', 'important');

In Angular, not so much. I have done an exhaustive search absolutely everywhere and can not find one single example for how to do this, so i am asking the question here.

Either Renderer2 in Angular is broken or i am just doing this wrong.

i import the following into my component:

import {ElementRef, Renderer2, RendererStyleFlags2 } from '@angular/core';

and, in my constructor:

constructor(private elRef: ElementRef,
            private renderer: Renderer2);

i set a style on an element in my template that works without issue:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff');

when i try to set the important flag like this:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', RendererStyleFlags2.Important);

or like this:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', flags:RendererStyleFlags2.Important);

or like this:

public myFlags:RendererStyleFlags2;
this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', myFlags.Important);

or in another way like this:

public myFlags:RendererStyleFlags2.Important;
public myFlags:RendererStyleFlags2.Important = 1;

along with many other attempts using arrays and objects:

myFlags:any = {important: 1}

None of the above works.

This is the method as it exists in angular core:

setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
    if (flags & RendererStyleFlags2.DashCase) {
      el.style.setProperty(
          style, value, !!(flags & RendererStyleFlags2.Important) ? 'important' : '');
    } else {
      el.style[style] = value;
    }
  }

Can anyone tell me what i am doing wrong here?

DevMike
  • 1,630
  • 2
  • 19
  • 33

2 Answers2

8

It feels like you either need to use both of the renderer flags or add !important to the string value instead.

const flags = RendererStyleFlags2.DashCase | RendererStyleFlags2.Important;
this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', flags);

Or

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff!important');
Daniel W Strimpel
  • 8,190
  • 2
  • 28
  • 38
  • WOW, OK so your first suggestion, setting both flags works, but can you help me understand what setting the DashCase does exactly? I did not see any other change in the DOM outside of the inclusion of the !important flag. – DevMike Apr 13 '18 at 18:46
  • Look at the code you posted from Angular core. It is checking for the `RendererStyleFlags2.DashCase` first to see which code path to go down. – Daniel W Strimpel Apr 13 '18 at 18:50
  • 1
    My best guess is that if you want to change the `borderRadius` property in CSS, you can specify it as `borderRadius` or `border-radius`. The way you are setting the CSS in JS dictates which way you have to specify the property. – Daniel W Strimpel Apr 13 '18 at 18:53
  • worst documentation, only shallow things are covered. If anything little bit complex we have to jump through API docs which don't have any clue on why a thing is there. You saved me after 2 hours of frustration. Thanks, Mr.Strimpel. – Vignesh Jun 06 '18 at 12:53
2

Another solution could be to overwrite the style attribute with the renderer, for example like this:

this.renderer.setAttribute(myElementHere, 'style', 'color: #FFF !important');

But warning, it will remove / overwrite already existing inline styles. For this case you could read the value of the current style attribute and append / prepend it to the value, which will be overwritten.

Note that this solution is a bit, I would say, hacky, but if you can deal with it, you're good to go.

I did no performance tests or something like that (setStyle vs setAttribute).

This is just to complete the possibilities of overwriting inline styles.

Unkn0wn0x
  • 1,031
  • 1
  • 12
  • 14