Shivam Jaiswal
Shivam Jaiswal

Reputation: 119

d3.select() returns null for a html element inside <ng-template>

I have a view which contains a < svg > element inside < ng-template>

<div *ngIf="data == undefined; else elseBlock">
   Sorry no data!
</div>
<ng-template #elseBlock>
   <svg id="areachart" width="100%" height="210"></svg>
</ng-template>

Using d3, I am trying to read width(baseValue) of the svg element, but d3.select('#areachart') returns me null in the code:

export class DrawAreaChart implements AfterViewInit {

    private data;

    constructor(){}

    ngAfterViewInit() {
       this.chartService.getData().subscribe(
           (result) => {
               if (result) {
                  this.data = result;

                  var svg = d3.select("#areachart"),
                  width = +svg.property("width").baseVal.value, /* The code fails here */
                  height = +svg.property("height").baseVal.value;

                  ....
                  ....
               }
           }
       );
    }
    ....
    ....
    ....
}

It throws error saying-

Cannot read property 'width' of null

Please help.

Upvotes: 1

Views: 1481

Answers (1)

Richard Matsen
Richard Matsen

Reputation: 23463

data is initially null, but after this.data = result Angular has not had time to adjust the DOM before d3 tries to select (so effectively svg is still not in the frame).

You can run the d3 code on ngOnChanges

ngOnChanges(changes: SimpleChanges) {
  if(changes.data) {
    // d3 code here
  }
}

or perhaps use [hidden]="!data" on the svg div (although some caveats around this, see What is the equivalent of ngShow and ngHide in Angular2).

Upvotes: 2

Related Questions