如何用API数据渲染Angular Highcharts?解决data赋值未定义报错
问题根源
- 异步数据加载时机不匹配:
chartOptionsTest作为类成员变量,会在组件实例化阶段立即初始化。此时API请求还未完成,this.moves是空数组,this.moves[1]为undefined,尝试访问undefined['Moves']必然抛出TypeError。你在ngOnInit里能打印出有效数据,是因为此时API请求已经完成、moves数组被填充,但这个时机晚于chartOptionsTest的初始化,错误早已触发。 - 未主动触发数据获取:从给出的代码示例看,
ngOnInit里没有调用getMoves()方法,这会导致moves数组永远无法被API返回的数据填充。
解决方案
方案1:先占位初始化,数据返回后更新图表
先给After系列的data设为空数组占位,等API数据加载完成后再更新图表配置:
export class CpmComponent implements OnInit { highcharts = Highcharts; chartOptionsTest: Highcharts.Options = { chart: { type: "spline" }, title: { text: "Simulated VS Actual Move" }, xAxis:{ categories:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }, yAxis: { title:{ text:"Moves" } }, tooltip: { valueSuffix:"" }, series: [ { name: 'Before', data: [1000, 5, 5, 5, 1000, 5, 5, 5, 1000, 5, 5, 5] }, { name: 'After', data: [] } ] }; moves: any[] = []; constructor(private DataService: DataService) {} ngOnInit(): void { this.getMoves(); // 主动调用数据获取方法 } getMoves() { this.DataService.getMovesFromDB().subscribe(movesArray => { this.moves = [...movesArray]; // 直接赋值确保数组更新 // 数据返回后更新After系列的data if (this.chartOptionsTest.series && this.moves.length > 1) { // Highcharts要求data是数组格式,单个数值需包装成数组 (this.chartOptionsTest.series[1] as any).data = [this.moves[1]['Moves']]; } }); } }
方案2:数据就绪后再初始化图表
如果希望图表仅在数据准备好后渲染,可以延迟chartOptionsTest的初始化:
export class CpmComponent implements OnInit { highcharts = Highcharts; chartOptionsTest?: Highcharts.Options; moves: any[] = []; constructor(private DataService: DataService) {} ngOnInit(): void { this.getMoves(); } getMoves() { this.DataService.getMovesFromDB().subscribe(movesArray => { this.moves = [...movesArray]; // 确认数据存在后再创建图表配置 if (this.moves.length > 1) { this.chartOptionsTest = { chart: { type: "spline" }, title: { text: "Simulated VS Actual Move" }, xAxis:{ categories:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }, yAxis: { title:{ text:"Moves" } }, tooltip: { valueSuffix:"" }, series: [ { name: 'Before', data: [1000, 5, 5, 5, 1000, 5, 5, 5, 1000, 5, 5, 5] }, { name: 'After', data: [this.moves[1]['Moves']] } ] }; } }); } }
同时在模板中添加判断,避免未初始化时渲染:
<highcharts-chart *ngIf="chartOptionsTest" [Highcharts]="highcharts" [options]="chartOptionsTest"></highcharts-chart>
额外注意点
- Highcharts的
series.data必须是数值数组,如果this.moves[1]['Moves']是单个数值,一定要包装成数组(比如[23352546]),否则图表无法正常渲染。 - 建议给
moves数组定义明确的类型(比如创建Move接口),避免any类型带来的潜在问题。
内容的提问来源于stack exchange,提问作者Chin
相关产品推荐
相关产品推荐

