首页 > 解决方案 > 使用 Angular 从 GET 请求创建图表时出现问题

问题描述

我正在尝试使用 REST 请求使用 Spring Boot 和 Angular 创建简单的 CRUD 数据库,并从中绘制一些图表。Spring boot 在 GET 请求后发送:

    "name" : "COVID",
    "infected": 500,
    "simulationTime": 3,
    "rvalue": 1.2,
    "dailyStatsList": [
        {
            "day": 1,
            "pv": 9500,
            "pr": 0,
            "pm": 0,
            "pi": 500
        },
        {
            "day": 2,
            "pv": 9392,
            "pr": 0,
            "pm": 0,
            "pi": 608
        },
        {
            "day": 3,
            "pv": 9260,
            "pr": 0,
            "pm": 0,
            "pi": 740
        }
    ]
}

这是我的 component.ts 文件:

export class SimulationDetailsComponent implements OnInit {
  currentSimulation!: SimulationWithStats;

  chartData = [
    { data: [10, 20, 30, 40, 50], label: 'Value1' },
    { data: [], label: 'Value2' },
    { data: [], label: 'Value3' },
  ];

  public chartLabel: string[] = ['1', '2', '3', '4', '5'];

  lineChartOptions = {
    responsive: true,
  };

  lineChartColors: Color[] = [
    {
      borderColor: 'black',
      backgroundColor: 'rgba(255,255,0,0.28)',
    },
  ];

  lineChartLegend = true;
  lineChartPlugins = [];
  lineChartType: ChartType = 'line';

  constructor(
    private controllerService: ControllerService,
    private route: ActivatedRoute,
    private router: Router
  ) {}

  ngOnInit(): void {
    var id = this.route.snapshot.params['id'];
    this.getSimulation(id);

    for (let i = 0; i < 5; i++) {       //THIS ONE WORKS FINE
      this.chartData[1].data.push(i * 2);
    }

    for (let dailyStats of this.currentSimulation.dailyStatsList) { //THIS DOESN'T WORK
      this.chartData[2].data.push(dailyStats.pi);
    }
  }

  getSimulation(id: string): void {
    this.controllerService.get(id).subscribe(
      (data) => {
        this.currentSimulation = data;
        console.log(data);
      },
      (error) => {
        console.log(error);
      }
    );
  }
}

不幸的是,它不起作用。看起来 currentSimulation 在我想填充我的 chartData [] 时没有初始化。我承认,currentSimulation 初始化很好,因为我可以在 html 页面上打印所有数据。可能是什么问题?你认为我应该在 chartData[] 填充之前等待一段时间吗?

标签: angularspringchart.js

解决方案


问题是您没有等待 http 调用返回实际数据。将方法更改getSimulation为如下所示:

async getSimulation(id: string): Promise<void> {
  try {
    this.currentSimulation = await this.controllerService.get(id).toPromise();
    console.log('current simulation data retrieved successfully', this.currentSimulation);
  } catch (error) {
    console.error('error retrieving current simulation', error);
  }
}

然后也做这个调整ngOnInit()

async ngOnInit(): Promise<void> {
  var id = this.route.snapshot.params['id'];
  await this.getSimulation(id);
  .............................
}

这应该可以解决问题。


顺便说一句,我不知道您使用的是哪个版本的 Angular,这就是我用于.toPromise()从 Observable 转换为 Promise 的原因。然而,在最新版本的 Angular(IIRC Angular 11+)上,lastValueFrom它是可以使用的,因为.toPromise()它已被弃用,迟早会被删除。

所以getSimulation理想情况下看起来像这样:

async getSimulation(id: string): Promise<void> {
  try {
    this.currentSimulation = await lastValueFrom(this.controllerService.get(id));
    console.log('current simulation data retrieved successfully', this.currentSimulation);
  } catch (error) {
    console.error('error retrieving current simulation', error);
  }
}

推荐阅读