使用 Angular 根据 GET 请求创建图表时出现问题

Problem creating chart out of GET request with Angular

我正在尝试使用 Spring Boot 和 Angular 使用 REST 请求创建简单的 CRUD 数据库,并从中绘制一些图表。 Spring 启动在 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[] 填充之前等待一段时间吗?

问题是您没有等待对 return 实际数据的 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);
  }
}