I am trying to draw a stacked bar chart using Kendo UI and angular. I want to pass data from home component to stacked bar chart component using service file. Home component console shows the dataset correctly but stacked bar chart component does not get the data as input.
Home component.ts
import { Component } from '@angular/core';
import { HomeService } from './home.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
homeData: any = [];
stackedbarchartdata: any = [];
constructor(private Data: HomeService) {
this.Data.getMethod().subscribe((res: any) => {
this.homeData = res;
this.stackedbarchartdata = this.homeData.stackedbarchartdata;
console.log(this.stackedbarchartdata);
})
}
ngOnInit() {}
}
home component.html
<kendo-tilelayout-item [col]="3" [colSpan]="2">
<kendo-tilelayout-item-body>
<app-stacked-bar-chart [stackedbarchartdata]="stackedbarchartdata"></app-stacked-bar-chart>
</kendo-tilelayout-item-body>
</kendo-tilelayout-item>
stacked-bar-chart.component.ts
import { Input } from '@angular/core';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-stacked-bar-chart',
templateUrl: './stacked-bar-chart.component.html',
styleUrls: ['./stacked-bar-chart.component.css']
})
export class StackedBarChartComponent implements OnInit {
@Input() stackedbarchartdata: any;
ngOnInit() {
console.log(this.stackedbarchartdata);
}
}
Json Data
"singleBaChartData": {
"name": "singleBaChartData-TOTAL REVENUE",
"Title": "TOTAL REVENUE",
"singleBaChartData": [{ "id": 1,"category": "product1","value": 5},
{ "id": 2,"category": "product2","value": 4}]}
CodePudding user response:
I am not familiar with Kendo TileLayout
and based on your comment, I can only assume the change detection of kendo-tilelayout-item
isn't picking up the changes to stackedbarchartdata
property. There are multiple options to try
1. Use async
pipe
You could remove the subscription in the component controller and use async
pipe in the template instead. This should trigger the subscription right from the template the provide the data to the @Input()
variable.
import { Component } from '@angular/core';
import { HomeService } from './home.service';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
homeData: any = [];
stackedbarchartdata$: Observable<any>;
constructor(private Data: HomeService) {
}
ngOnInit() {
this.stackedbarchartdata$ = this.Data.getMethod().pipe(
tap((res: any) => this.homeData = res), // <-- is this needed anymore?
map((res: any) => res.stackedbarchartdata)
);
}
}
<kendo-tilelayout-item [col]="3" [colSpan]="2">
<kendo-tilelayout-item-body>
<app-stacked-bar-chart [stackedbarchartdata]="stackedbarchartdata$ | async"></app-stacked-bar-chart>
</kendo-tilelayout-item-body>
</kendo-tilelayout-item>
2. Manually trigger change detection
There are multiple ways to trigger the change detection manually inside the subscription callback after the property stackedbarchartdata
is assigned the value. Although I find this a little inelegant.