Reputation: 1245
In my angular-7 project, I am trying to make an html page with nested material tabs where in second tab will have another set of tabs. In second tab, trying to make canvas chart for data passed to child component.
Here is my html code.
<mat-tab-group mat-stretch-tabs [selectedIndex]="0">
<mat-tab label="Sales"> Sales
</mat-tab>
<mat-tab label="Purchase">
<!-- <ng-template matTabContent> //This block works but i want in tab format
<div *ngIf="isReady " class="divinput ">
<div *ngFor="let d of data">
<draw [input]="d "></draw>
</div>
</div>
</ng-template> -->
<mat-tab-group *ngIf="isReady"> // this throws error
<mat-tab *ngIf="isReady" label="north">
<ng-template matTabContent>
<div *ngFor="let d of data">
<draw [input]="d"></draw>
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</mat-tab>
</mat-tab-group>
The above code calls a child component "draw" which has function to draw chart.
private draw (chart){
var canvas = <HTMLCanvasElement> document.getElementById(chart.id);
var ctx = canvas.getContext("2d");
return new Chart(ctx, {
type: 'line',
data: {labels: chart.x,datasets: mydata}
})
}
this throws error , TypeError: Cannot read property 'getContext' of null
for line var ctx = canvas.getContext("2d");
in function draw. It looks like material-tabs does not wait for data to be available. I tried to handle this by "isReady" but no luck.
One strange thing i noticed that, it works when I change [selectedIndex]="0"
to [selectedIndex]="1"
. But can not consider this as first tab should be active on load as per requirement.
I struggling hard to figure out the problem. Please help to resolve the issue.
Upvotes: 0
Views: 1448
Reputation: 2795
in angular specifically you can use ViewChild
instead of getElementById to get canvas
in angular 7 specifically it will work as follow
component.html
<canvas #chart></canvas>
component.ts
import { Component, OnInit, ViewChild, ElementRef, Input } from '@angular/core';
@Component({
selector: 'app-draw',
templateUrl: './draw.component.html',
styleUrls: ['./draw.component.css']
})
export class DrawComponent implements OnInit {
@ViewChild('chart')
chartElementRef: ElementRef<HTMLCanvasElement>;
@Input()
input: any;
constructor() { }
ngOnInit() {
this.draw();
}
private draw () {
const canvas = this.chartElementRef.nativeElement;
const ctx = canvas.getContext("2d");
}
}
Upvotes: 1