How to get a value from a stylesheet into the code so that it can be used programmatically?

Viewed 541

I'm working on an Angular 8 app, and we use global styles. I'm using the D3 chart library in the app and to set a style, you have to configure it in code. For example:

plottingArea.append('text')
    .attr('fill', '#00B2B3');

This will change the color of the text used in the D3 graph (svg). But since we use global styles, I need to find a way to pull this value into code so that if the style changes at some point, I won't have to change the code.

I tried creating a class selector and adding the color there, then adding the class to the html element that's being used for the chart (in this case, a div), then using @ViewChild to query for the class to get the color property value:

component.scss

.my-color {
  color: global-style('text', 'grey');
}

component.html

<div #my-div class="my-color"></div>

component.ts

@ViewChild('my-div', { static: false }) myDiv!: ElementRef;

ngAfterViewInit() {
  
  //this returns empty string
  const color = this.myDiv.nativeElement.style.color;

  //this returns null
  const style = this.myDiv.nativeElement.querySelector('.my-color');

}

So since I can't access the color value like that, I'm not sure how to do it.

3 Answers

You can use getComputedStyle:

const color = window.getComputedStyle(this.myDiv.nativeElement).color;

If you are having issues getting the style with window.getComputedStyle, I think you may need to wait until the DOM is rendered in ngAfterViewInit, and check for changes to the DOM re-rendering in ngOnChanges

I think the best way would be to create a directive which can access the DOM.

@Directive({
  selector: '[color-getter]'
})

export class ColorGetter {
  constructor(public el: ElementRef) {}
  ngOnChanges() {
    setTimeout(() => {
      console.log(this.el.nativeElement.style.color);
    })
  }
  ngAfterViewInit() {
    console.log(this.el.nativeElement.style.color);
  }
}

The best way is to use a directive through which you can get access to the native DOM element to which this directive is applied. Then you can wait until the DOM is rendered in AfterViewInit hook and use getComputedStyle method to get all computed styles.

This is what I ended up having to do:

component.scss

.my-color {
  fill: global-style('text', 'grey');
}

component.html

<div #my-div class="my-color"></div>

component.ts

plottingArea.append('text')
    .classed('my-color', true)

The classed() methods was the answer. But I'm still not sure why I wasn't able to get the value of a style.

Related